wrfrun 0.1.8__py3-none-any.whl → 0.2.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/cli.py +131 -0
- wrfrun/core/base.py +52 -19
- wrfrun/core/config.py +257 -170
- wrfrun/core/error.py +8 -1
- wrfrun/core/replay.py +1 -1
- wrfrun/core/server.py +91 -71
- wrfrun/data.py +14 -16
- wrfrun/extension/goos_sst/__init__.py +5 -5
- wrfrun/extension/goos_sst/core.py +4 -1
- wrfrun/extension/goos_sst/res/Vtable.ERA_GOOS_SST +1 -1
- wrfrun/extension/goos_sst/res/__init__.py +17 -0
- wrfrun/extension/goos_sst/utils.py +21 -5
- wrfrun/extension/littler/__init__.py +57 -1
- wrfrun/extension/littler/{utils.py → core.py} +329 -43
- wrfrun/extension/utils.py +24 -22
- wrfrun/model/__init__.py +24 -1
- wrfrun/model/plot.py +259 -36
- wrfrun/model/utils.py +19 -9
- wrfrun/model/wrf/__init__.py +41 -0
- wrfrun/model/wrf/core.py +229 -101
- wrfrun/model/wrf/exec_wrap.py +49 -35
- wrfrun/model/wrf/geodata.py +2 -1
- wrfrun/model/wrf/namelist.py +78 -4
- wrfrun/model/wrf/{_metgrid.py → utils.py} +38 -3
- wrfrun/model/wrf/vtable.py +9 -5
- wrfrun/res/__init__.py +22 -7
- wrfrun/res/config/config.template.toml +57 -0
- wrfrun/res/{config.toml.template → config/wrf.template.toml} +7 -46
- 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 +39 -27
- wrfrun/scheduler/__init__.py +35 -0
- wrfrun/scheduler/env.py +44 -0
- wrfrun/scheduler/lsf.py +49 -0
- wrfrun/scheduler/pbs.py +50 -0
- wrfrun/scheduler/script.py +72 -0
- wrfrun/scheduler/slurm.py +50 -0
- wrfrun/scheduler/utils.py +14 -0
- wrfrun/utils.py +8 -3
- wrfrun/workspace/__init__.py +38 -0
- wrfrun/workspace/core.py +94 -0
- wrfrun/workspace/wrf.py +165 -0
- {wrfrun-0.1.8.dist-info → wrfrun-0.2.0.dist-info}/METADATA +3 -2
- wrfrun-0.2.0.dist-info/RECORD +62 -0
- wrfrun-0.2.0.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.8.dist-info/RECORD +0 -51
- {wrfrun-0.1.8.dist-info → wrfrun-0.2.0.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, NamelistIDError, WRFRUNConfig, WRFRUNExecDB
|
|
27
|
+
from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistIDError, WRFRUNConfig, WRFRUNExecDB, get_wrfrun_config
|
|
7
28
|
from wrfrun.utils import logger
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
|
|
29
|
+
from wrfrun.workspace.wrf import get_wrf_workspace_path
|
|
30
|
+
from .namelist import (get_ungrib_out_dir_path, get_ungrib_out_prefix, prepare_dfi_namelist, prepare_wps_namelist, prepare_wrf_namelist, prepare_wrfda_namelist,
|
|
31
|
+
set_metgrid_fg_names, set_ungrib_out_prefix)
|
|
32
|
+
from .utils import process_after_ndown, reconcile_namelist_metgrid
|
|
11
33
|
from .vtable import VtableFiles
|
|
12
34
|
from ..base import NamelistName
|
|
13
35
|
|
|
14
36
|
|
|
15
|
-
def
|
|
16
|
-
|
|
37
|
+
def _check_and_prepare_namelist():
|
|
38
|
+
"""
|
|
39
|
+
This function check if namelists needed by WPS/WRF have been loaded,
|
|
40
|
+
and prepare namelist if check fails.
|
|
41
|
+
"""
|
|
42
|
+
wrfrun_config = get_wrfrun_config()
|
|
43
|
+
if not wrfrun_config.check_namelist("wps"):
|
|
17
44
|
prepare_wps_namelist()
|
|
18
45
|
|
|
19
|
-
if
|
|
46
|
+
if not wrfrun_config.check_namelist("wrf"):
|
|
20
47
|
prepare_wrf_namelist()
|
|
21
48
|
|
|
22
|
-
if
|
|
49
|
+
if not wrfrun_config.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=get_wrf_workspace_path('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"{get_wrf_workspace_path('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"{get_wrf_workspace_path('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=get_wrf_workspace_path('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"{get_wrf_workspace_path('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"{get_wrf_workspace_path('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=get_wrf_workspace_path('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": get_wrf_workspace_path('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"{get_wrf_workspace_path('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=get_wrf_workspace_path('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(get_wrf_workspace_path('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": get_wrf_workspace_path('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,11 @@ class MetGrid(ExecutableBase):
|
|
|
352
427
|
|
|
353
428
|
super().before_exec()
|
|
354
429
|
|
|
355
|
-
WRFRUNConfig.write_namelist(f"{
|
|
430
|
+
WRFRUNConfig.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
|
|
431
|
+
|
|
432
|
+
# print debug logs
|
|
433
|
+
logger.debug("Namelist settings of 'metgrid':")
|
|
434
|
+
logger.debug(WRFRUNConfig.get_namelist("wps"))
|
|
356
435
|
|
|
357
436
|
def after_exec(self):
|
|
358
437
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -366,16 +445,17 @@ class MetGrid(ExecutableBase):
|
|
|
366
445
|
|
|
367
446
|
class Real(ExecutableBase):
|
|
368
447
|
"""
|
|
369
|
-
|
|
448
|
+
``Executable`` of "real.exe".
|
|
370
449
|
"""
|
|
371
450
|
|
|
372
451
|
def __init__(self, metgrid_data_path: Optional[str] = None, core_num: Optional[int] = None):
|
|
373
452
|
"""
|
|
374
|
-
|
|
453
|
+
``Executable`` of "real.exe".
|
|
375
454
|
|
|
376
|
-
:param metgrid_data_path:
|
|
455
|
+
:param metgrid_data_path: Directory path of :class:`MetGrid` outputs.
|
|
456
|
+
If is ``None``, try to use the workspace path or output path in the config file.
|
|
377
457
|
:type metgrid_data_path: str
|
|
378
|
-
:param core_num: An positive integer number
|
|
458
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
379
459
|
:type core_num: int
|
|
380
460
|
"""
|
|
381
461
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -392,13 +472,19 @@ class Real(ExecutableBase):
|
|
|
392
472
|
mpi_cmd = "mpirun"
|
|
393
473
|
mpi_core_num = core_num
|
|
394
474
|
|
|
395
|
-
|
|
475
|
+
_check_and_prepare_namelist()
|
|
396
476
|
|
|
397
|
-
super().__init__(name="real", cmd="./real.exe", work_path=
|
|
477
|
+
super().__init__(name="real", cmd="./real.exe", work_path=get_wrf_workspace_path('wrf'), mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
398
478
|
|
|
399
479
|
self.metgrid_data_path = metgrid_data_path
|
|
400
480
|
|
|
401
481
|
def generate_custom_config(self):
|
|
482
|
+
"""
|
|
483
|
+
Store custom configs, including:
|
|
484
|
+
|
|
485
|
+
1. Namelist settings.
|
|
486
|
+
2. Directory path of :class:`MetGrid` outputs.
|
|
487
|
+
"""
|
|
402
488
|
self.custom_config["metgrid_data_path"] = self.metgrid_data_path
|
|
403
489
|
self.custom_config.update(
|
|
404
490
|
{
|
|
@@ -408,6 +494,9 @@ class Real(ExecutableBase):
|
|
|
408
494
|
)
|
|
409
495
|
|
|
410
496
|
def load_custom_config(self):
|
|
497
|
+
"""
|
|
498
|
+
Load custom configs.
|
|
499
|
+
"""
|
|
411
500
|
self.metgrid_data_path = self.custom_config["metgrid_data_path"]
|
|
412
501
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
|
|
413
502
|
|
|
@@ -426,7 +515,7 @@ class Real(ExecutableBase):
|
|
|
426
515
|
for _file in file_list:
|
|
427
516
|
_file_config: FileConfigDict = {
|
|
428
517
|
"file_path": f"{self.metgrid_data_path}/{_file}",
|
|
429
|
-
"save_path":
|
|
518
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
430
519
|
"save_name": _file,
|
|
431
520
|
"is_data": True,
|
|
432
521
|
"is_output": True
|
|
@@ -435,7 +524,11 @@ class Real(ExecutableBase):
|
|
|
435
524
|
|
|
436
525
|
super().before_exec()
|
|
437
526
|
|
|
438
|
-
WRFRUNConfig.write_namelist(f"{
|
|
527
|
+
WRFRUNConfig.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
528
|
+
|
|
529
|
+
# print debug logs
|
|
530
|
+
logger.debug("Namelist settings of 'real':")
|
|
531
|
+
logger.debug(WRFRUNConfig.get_namelist("wrf"))
|
|
439
532
|
|
|
440
533
|
def after_exec(self):
|
|
441
534
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -449,20 +542,20 @@ class Real(ExecutableBase):
|
|
|
449
542
|
|
|
450
543
|
class WRF(ExecutableBase):
|
|
451
544
|
"""
|
|
452
|
-
|
|
545
|
+
``Executable`` of "wrf.exe".
|
|
453
546
|
"""
|
|
454
547
|
|
|
455
548
|
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
549
|
"""
|
|
457
|
-
|
|
550
|
+
``Executable`` of "wrf.exe"
|
|
458
551
|
|
|
459
|
-
:param input_file_dir_path:
|
|
552
|
+
:param input_file_dir_path: Directory path of input data.
|
|
460
553
|
:type input_file_dir_path: str
|
|
461
|
-
:param restart_file_dir_path:
|
|
554
|
+
:param restart_file_dir_path: Directory path of restart files.
|
|
462
555
|
:type restart_file_dir_path: str
|
|
463
|
-
:param save_restarts: If saving restart files
|
|
556
|
+
:param save_restarts: If saving restart files. Defaults to False.
|
|
464
557
|
:type save_restarts: bool
|
|
465
|
-
:param core_num: An positive integer number
|
|
558
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
466
559
|
:type core_num: int
|
|
467
560
|
"""
|
|
468
561
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -479,15 +572,22 @@ class WRF(ExecutableBase):
|
|
|
479
572
|
mpi_cmd = "mpirun"
|
|
480
573
|
mpi_core_num = core_num
|
|
481
574
|
|
|
482
|
-
|
|
575
|
+
_check_and_prepare_namelist()
|
|
483
576
|
|
|
484
|
-
super().__init__(name="wrf", cmd="./wrf.exe", work_path=
|
|
577
|
+
super().__init__(name="wrf", cmd="./wrf.exe", work_path=get_wrf_workspace_path('wrf'), mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
485
578
|
|
|
486
579
|
self.input_file_dir_path = input_file_dir_path
|
|
487
580
|
self.restart_file_dir_path = restart_file_dir_path
|
|
488
581
|
self.save_restarts = save_restarts
|
|
489
582
|
|
|
490
583
|
def generate_custom_config(self):
|
|
584
|
+
"""
|
|
585
|
+
Store custom configs, including:
|
|
586
|
+
|
|
587
|
+
1. Directory path of input datas.
|
|
588
|
+
2. Directory path of restart files.
|
|
589
|
+
3. Namelist settings.
|
|
590
|
+
"""
|
|
491
591
|
self.custom_config.update(
|
|
492
592
|
{
|
|
493
593
|
"input_file_dir_path": self.input_file_dir_path,
|
|
@@ -497,6 +597,9 @@ class WRF(ExecutableBase):
|
|
|
497
597
|
)
|
|
498
598
|
|
|
499
599
|
def load_custom_config(self):
|
|
600
|
+
"""
|
|
601
|
+
Load custom configs.
|
|
602
|
+
"""
|
|
500
603
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
501
604
|
self.restart_file_dir_path = self.custom_config["restart_file_dir_path"]
|
|
502
605
|
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
|
|
@@ -530,7 +633,7 @@ class WRF(ExecutableBase):
|
|
|
530
633
|
for _file in file_list:
|
|
531
634
|
_file_config: FileConfigDict = {
|
|
532
635
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
533
|
-
"save_path":
|
|
636
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
534
637
|
"save_name": _file,
|
|
535
638
|
"is_data": True,
|
|
536
639
|
"is_output": is_output
|
|
@@ -552,7 +655,7 @@ class WRF(ExecutableBase):
|
|
|
552
655
|
for _file in file_list:
|
|
553
656
|
_file_config: FileConfigDict = {
|
|
554
657
|
"file_path": f"{self.restart_file_dir_path}/{_file}",
|
|
555
|
-
"save_path":
|
|
658
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
556
659
|
"save_name": _file,
|
|
557
660
|
"is_data": True,
|
|
558
661
|
"is_output": False
|
|
@@ -561,7 +664,11 @@ class WRF(ExecutableBase):
|
|
|
561
664
|
|
|
562
665
|
super().before_exec()
|
|
563
666
|
|
|
564
|
-
WRFRUNConfig.write_namelist(f"{
|
|
667
|
+
WRFRUNConfig.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
668
|
+
|
|
669
|
+
# print debug logs
|
|
670
|
+
logger.debug("Namelist settings of 'wrf':")
|
|
671
|
+
logger.debug(WRFRUNConfig.get_namelist("wrf"))
|
|
565
672
|
|
|
566
673
|
def after_exec(self):
|
|
567
674
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -578,18 +685,18 @@ class WRF(ExecutableBase):
|
|
|
578
685
|
|
|
579
686
|
class DFI(ExecutableBase):
|
|
580
687
|
"""
|
|
581
|
-
|
|
688
|
+
``Executable`` to run DFI.
|
|
582
689
|
"""
|
|
583
690
|
|
|
584
691
|
def __init__(self, input_file_dir_path: Optional[str] = None, update_real_output=True, core_num: Optional[int] = None):
|
|
585
692
|
"""
|
|
586
|
-
|
|
693
|
+
``Executable`` to run DFI.
|
|
587
694
|
|
|
588
|
-
:param input_file_dir_path:
|
|
695
|
+
:param input_file_dir_path: Directory path of input data.
|
|
589
696
|
:type input_file_dir_path: str
|
|
590
|
-
:param update_real_output: If update
|
|
697
|
+
:param update_real_output: If update corresponding files in :class:`Real` outputs.
|
|
591
698
|
:type update_real_output: bool
|
|
592
|
-
:param core_num: An positive integer number
|
|
699
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
593
700
|
:type core_num: int
|
|
594
701
|
"""
|
|
595
702
|
if isinstance(core_num, int) and core_num <= 0:
|
|
@@ -606,12 +713,19 @@ class DFI(ExecutableBase):
|
|
|
606
713
|
mpi_cmd = "mpirun"
|
|
607
714
|
mpi_core_num = core_num
|
|
608
715
|
|
|
609
|
-
super().__init__(name="dfi", cmd="./wrf.exe", work_path=
|
|
716
|
+
super().__init__(name="dfi", cmd="./wrf.exe", work_path=get_wrf_workspace_path('wrf'), mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
610
717
|
|
|
611
718
|
self.input_file_dir_path = input_file_dir_path
|
|
612
719
|
self.update_real_output = update_real_output
|
|
613
720
|
|
|
614
721
|
def generate_custom_config(self):
|
|
722
|
+
"""
|
|
723
|
+
Store custom configs, including:
|
|
724
|
+
|
|
725
|
+
1. Directory path of input datas.
|
|
726
|
+
2. If update corresponding files in :class:`Real` outputs.
|
|
727
|
+
3. Namelist settings.
|
|
728
|
+
"""
|
|
615
729
|
self.custom_config.update(
|
|
616
730
|
{
|
|
617
731
|
"input_file_dir_path": self.input_file_dir_path,
|
|
@@ -621,6 +735,9 @@ class DFI(ExecutableBase):
|
|
|
621
735
|
)
|
|
622
736
|
|
|
623
737
|
def load_custom_config(self):
|
|
738
|
+
"""
|
|
739
|
+
Load custom configs.
|
|
740
|
+
"""
|
|
624
741
|
self.input_file_dir_path = self.custom_config["input_file_dir_path"]
|
|
625
742
|
self.update_real_output = self.custom_config["update_real_output"]
|
|
626
743
|
|
|
@@ -650,7 +767,7 @@ class DFI(ExecutableBase):
|
|
|
650
767
|
for _file in file_list:
|
|
651
768
|
_file_config: FileConfigDict = {
|
|
652
769
|
"file_path": f"{self.input_file_dir_path}/{_file}",
|
|
653
|
-
"save_path":
|
|
770
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
654
771
|
"save_name": _file,
|
|
655
772
|
"is_data": True,
|
|
656
773
|
"is_output": is_output
|
|
@@ -664,7 +781,7 @@ class DFI(ExecutableBase):
|
|
|
664
781
|
prepare_dfi_namelist()
|
|
665
782
|
|
|
666
783
|
super().before_exec()
|
|
667
|
-
WRFRUNConfig.write_namelist(f"{
|
|
784
|
+
WRFRUNConfig.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "dfi")
|
|
668
785
|
|
|
669
786
|
def after_exec(self):
|
|
670
787
|
if not WRFRUNConfig.IS_IN_REPLAY:
|
|
@@ -686,21 +803,21 @@ class DFI(ExecutableBase):
|
|
|
686
803
|
|
|
687
804
|
class NDown(ExecutableBase):
|
|
688
805
|
"""
|
|
689
|
-
|
|
806
|
+
``Executable`` of "ndown.exe".
|
|
690
807
|
"""
|
|
691
808
|
|
|
692
809
|
def __init__(self, wrfout_file_path: str, real_output_dir_path: Optional[str] = None, update_namelist=True, core_num: Optional[int] = None):
|
|
693
810
|
"""
|
|
694
|
-
|
|
811
|
+
``Executable`` of "ndown.exe".
|
|
695
812
|
|
|
696
813
|
:param wrfout_file_path: wrfout file path.
|
|
697
814
|
:type wrfout_file_path: str
|
|
698
|
-
:param real_output_dir_path:
|
|
815
|
+
:param real_output_dir_path: Directory path of :class:`Real` outputs.
|
|
699
816
|
:type real_output_dir_path: str
|
|
700
|
-
:param update_namelist: If update
|
|
817
|
+
:param update_namelist: If update namelist settings for the final integral.
|
|
701
818
|
:type update_namelist: bool
|
|
702
|
-
:param core_num:
|
|
703
|
-
:type core_num:
|
|
819
|
+
:param core_num: An positive integer number. ``mpirun`` will be used to execute geogrid.exe if ``core_num != None``.
|
|
820
|
+
:type core_num: int
|
|
704
821
|
"""
|
|
705
822
|
if isinstance(core_num, int) and core_num <= 0:
|
|
706
823
|
logger.warning(f"`core_num` should be greater than 0")
|
|
@@ -716,15 +833,23 @@ class NDown(ExecutableBase):
|
|
|
716
833
|
mpi_cmd = "mpirun"
|
|
717
834
|
mpi_core_num = core_num
|
|
718
835
|
|
|
719
|
-
|
|
836
|
+
_check_and_prepare_namelist()
|
|
720
837
|
|
|
721
|
-
super().__init__(name="ndown", cmd="./ndown.exe", work_path=
|
|
838
|
+
super().__init__(name="ndown", cmd="./ndown.exe", work_path=get_wrf_workspace_path('wrf'), mpi_use=mpi_use, mpi_cmd=mpi_cmd, mpi_core_num=mpi_core_num)
|
|
722
839
|
|
|
723
840
|
self.wrfout_file_path = wrfout_file_path
|
|
724
841
|
self.real_output_dir_path = real_output_dir_path
|
|
725
842
|
self.update_namelist = update_namelist
|
|
726
843
|
|
|
727
844
|
def generate_custom_config(self):
|
|
845
|
+
"""
|
|
846
|
+
Store custom configs, including:
|
|
847
|
+
|
|
848
|
+
1. Positional arguments of this ``Executable``.
|
|
849
|
+
2. Directory path of :class:`Real` outputs.
|
|
850
|
+
3. If update namelist settings.
|
|
851
|
+
4. Namelist settings.
|
|
852
|
+
"""
|
|
728
853
|
self.class_config["class_args"] = (self.wrfout_file_path,)
|
|
729
854
|
self.custom_config.update(
|
|
730
855
|
{
|
|
@@ -735,9 +860,12 @@ class NDown(ExecutableBase):
|
|
|
735
860
|
)
|
|
736
861
|
|
|
737
862
|
def load_custom_config(self):
|
|
863
|
+
"""
|
|
864
|
+
Load custom configs.
|
|
865
|
+
"""
|
|
738
866
|
self.real_output_dir_path = self.custom_config["real_output_dir_path"]
|
|
739
867
|
self.update_namelist = self.custom_config["update_namelist"]
|
|
740
|
-
WRFRUNConfig.update_namelist(self.custom_config["namelist"])
|
|
868
|
+
WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
|
|
741
869
|
|
|
742
870
|
def before_exec(self):
|
|
743
871
|
WRFRUNConfig.check_wrfrun_context(True)
|
|
@@ -756,14 +884,14 @@ class NDown(ExecutableBase):
|
|
|
756
884
|
|
|
757
885
|
wrfndi_file_config: FileConfigDict = {
|
|
758
886
|
"file_path": f"{self.real_output_dir_path}/wrfinput_d02",
|
|
759
|
-
"save_path":
|
|
887
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
760
888
|
"save_name": "wrfndi_d02",
|
|
761
889
|
"is_data": True,
|
|
762
890
|
"is_output": is_output
|
|
763
891
|
}
|
|
764
892
|
wrfout_file_config: FileConfigDict = {
|
|
765
893
|
"file_path": self.wrfout_file_path,
|
|
766
|
-
"save_path":
|
|
894
|
+
"save_path": get_wrf_workspace_path('wrf'),
|
|
767
895
|
"save_name": "wrfout_d01",
|
|
768
896
|
"is_data": True,
|
|
769
897
|
"is_output": False
|
|
@@ -773,7 +901,7 @@ class NDown(ExecutableBase):
|
|
|
773
901
|
|
|
774
902
|
super().before_exec()
|
|
775
903
|
|
|
776
|
-
WRFRUNConfig.write_namelist(f"{
|
|
904
|
+
WRFRUNConfig.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
|
|
777
905
|
|
|
778
906
|
def after_exec(self):
|
|
779
907
|
self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
|