wrfrun 0.1.9__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.
Files changed (66) hide show
  1. wrfrun/__init__.py +8 -3
  2. wrfrun/cli.py +74 -31
  3. wrfrun/core/__init__.py +27 -10
  4. wrfrun/core/_config.py +308 -0
  5. wrfrun/core/_constant.py +236 -0
  6. wrfrun/core/_exec_db.py +105 -0
  7. wrfrun/core/_namelist.py +287 -0
  8. wrfrun/core/_record.py +178 -0
  9. wrfrun/core/_resource.py +172 -0
  10. wrfrun/core/base.py +136 -380
  11. wrfrun/core/core.py +196 -0
  12. wrfrun/core/error.py +35 -2
  13. wrfrun/core/replay.py +10 -96
  14. wrfrun/core/server.py +74 -32
  15. wrfrun/core/type.py +171 -0
  16. wrfrun/data.py +312 -149
  17. wrfrun/extension/goos_sst/__init__.py +2 -2
  18. wrfrun/extension/goos_sst/core.py +9 -14
  19. wrfrun/extension/goos_sst/res/__init__.py +0 -1
  20. wrfrun/extension/goos_sst/utils.py +50 -44
  21. wrfrun/extension/littler/core.py +105 -88
  22. wrfrun/extension/utils.py +5 -3
  23. wrfrun/log.py +117 -0
  24. wrfrun/model/__init__.py +11 -7
  25. wrfrun/model/constants.py +52 -0
  26. wrfrun/model/palm/__init__.py +30 -0
  27. wrfrun/model/palm/core.py +145 -0
  28. wrfrun/model/palm/namelist.py +33 -0
  29. wrfrun/model/plot.py +99 -114
  30. wrfrun/model/type.py +116 -0
  31. wrfrun/model/utils.py +9 -19
  32. wrfrun/model/wrf/__init__.py +4 -9
  33. wrfrun/model/wrf/core.py +262 -165
  34. wrfrun/model/wrf/exec_wrap.py +13 -12
  35. wrfrun/model/wrf/geodata.py +116 -99
  36. wrfrun/model/wrf/log.py +103 -0
  37. wrfrun/model/wrf/namelist.py +92 -76
  38. wrfrun/model/wrf/plot.py +102 -0
  39. wrfrun/model/wrf/scheme.py +108 -52
  40. wrfrun/model/wrf/utils.py +39 -24
  41. wrfrun/model/wrf/vtable.py +42 -7
  42. wrfrun/plot/__init__.py +20 -0
  43. wrfrun/plot/wps.py +90 -73
  44. wrfrun/res/__init__.py +115 -5
  45. wrfrun/res/config/config.template.toml +15 -0
  46. wrfrun/res/config/palm.template.toml +23 -0
  47. wrfrun/run.py +121 -77
  48. wrfrun/scheduler/__init__.py +1 -0
  49. wrfrun/scheduler/lsf.py +4 -1
  50. wrfrun/scheduler/pbs.py +4 -1
  51. wrfrun/scheduler/script.py +19 -5
  52. wrfrun/scheduler/slurm.py +4 -1
  53. wrfrun/scheduler/utils.py +14 -2
  54. wrfrun/utils.py +88 -199
  55. wrfrun/workspace/__init__.py +8 -5
  56. wrfrun/workspace/core.py +21 -11
  57. wrfrun/workspace/palm.py +137 -0
  58. wrfrun/workspace/wrf.py +59 -14
  59. wrfrun-0.3.0.dist-info/METADATA +240 -0
  60. wrfrun-0.3.0.dist-info/RECORD +78 -0
  61. wrfrun/core/config.py +0 -767
  62. wrfrun/model/base.py +0 -14
  63. wrfrun-0.1.9.dist-info/METADATA +0 -68
  64. wrfrun-0.1.9.dist-info/RECORD +0 -62
  65. {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
  66. {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/model/wrf/core.py CHANGED
@@ -24,29 +24,38 @@ from os.path import abspath, basename, exists
24
24
  from shutil import copyfile, move, rmtree
25
25
  from typing import Optional, Union
26
26
 
27
- from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistIDError, WRFRUNConfig, WRFRUNExecDB
28
- from wrfrun.workspace.wrf import WORKSPACE_MODEL_WPS, WORKSPACE_MODEL_WRF
29
- from wrfrun.utils import logger
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)
27
+ from wrfrun.core import WRFRUN, ExecutableBase, ExecutableDB, FileConfigDict, InputFileError, NamelistIDError
28
+ from wrfrun.log import logger
29
+ from wrfrun.workspace.wrf import get_wrf_workspace_path
30
+
31
+ from ..constants import NamelistName
32
+ from .namelist import (
33
+ get_ungrib_out_dir_path,
34
+ get_ungrib_out_prefix,
35
+ prepare_dfi_namelist,
36
+ prepare_wps_namelist,
37
+ prepare_wrf_namelist,
38
+ prepare_wrfda_namelist,
39
+ set_metgrid_fg_names,
40
+ set_ungrib_out_prefix,
41
+ )
42
+ from .utils import process_after_ndown, reconcile_namelist_metgrid
34
43
  from .vtable import VtableFiles
35
- from ..base import NamelistName
36
44
 
37
45
 
38
46
  def _check_and_prepare_namelist():
39
47
  """
40
- This function check if namelists needed by WPS/WRF have been loaded,
41
- and prepare namelist if check fails.
48
+ This function check if namelists needed by WPS/WRF have been loaded.
49
+ If not, call :doc:`preparation function </api/model.wrf.namelist>` to load them.
42
50
  """
43
- if not WRFRUNConfig.check_namelist("wps"):
51
+ wrfrun_config = WRFRUN.config
52
+ if not wrfrun_config.check_namelist("wps"):
44
53
  prepare_wps_namelist()
45
54
 
46
- if not WRFRUNConfig.check_namelist("wrf"):
55
+ if not wrfrun_config.check_namelist("wrf"):
47
56
  prepare_wrf_namelist()
48
57
 
49
- if not WRFRUNConfig.check_namelist("wrfda"):
58
+ if not wrfrun_config.check_namelist("wrfda"):
50
59
  prepare_wrfda_namelist()
51
60
 
52
61
 
@@ -65,7 +74,7 @@ class GeoGrid(ExecutableBase):
65
74
  :type core_num: int
66
75
  """
67
76
  if isinstance(core_num, int) and core_num <= 0:
68
- logger.warning(f"`core_num` should be greater than 0")
77
+ logger.warning("`core_num` should be greater than 0")
69
78
  core_num = None
70
79
 
71
80
  if core_num is None:
@@ -78,7 +87,14 @@ class GeoGrid(ExecutableBase):
78
87
  mpi_cmd = "mpirun"
79
88
  mpi_core_num = core_num
80
89
 
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)
90
+ super().__init__(
91
+ name="geogrid",
92
+ cmd="./geogrid.exe",
93
+ work_path=get_wrf_workspace_path("wps"),
94
+ mpi_use=mpi_use,
95
+ mpi_cmd=mpi_cmd,
96
+ mpi_core_num=mpi_core_num,
97
+ )
82
98
 
83
99
  self.geogrid_tbl_file = geogrid_tbl_file
84
100
 
@@ -91,48 +107,46 @@ class GeoGrid(ExecutableBase):
91
107
  1. Namelist settings.
92
108
  2. Path of custom TBL file.
93
109
  """
94
- self.custom_config.update(
95
- {
96
- "namelist": WRFRUNConfig.get_namelist("wps"),
97
- "geogrid_tbl_file": self.geogrid_tbl_file
98
- }
99
- )
110
+ self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wps"), "geogrid_tbl_file": self.geogrid_tbl_file})
100
111
 
101
112
  def load_custom_config(self):
102
113
  """
103
114
  Load custom configs.
104
115
  """
105
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
116
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
106
117
  self.geogrid_tbl_file = self.custom_config["geogrid_tbl_file"]
107
118
 
108
119
  def before_exec(self):
109
- WRFRUNConfig.check_wrfrun_context(True)
110
- WRFRUNConfig.WRFRUN_WORK_STATUS = "geogrid"
120
+ WRFRUN.config.check_wrfrun_context(True)
121
+ WRFRUN.config.WRFRUN_WORK_STATUS = "geogrid"
111
122
 
112
- if not WRFRUNConfig.IS_IN_REPLAY:
123
+ if not WRFRUN.config.IS_IN_REPLAY:
113
124
  if self.geogrid_tbl_file is not None:
114
125
  tbl_file: FileConfigDict = {
115
- "file_path": self.geogrid_tbl_file, "save_path": f"{WORKSPACE_MODEL_WPS}/geogrid",
116
- "save_name": "GEOGRID.TBL", "is_data": False, "is_output": False
126
+ "file_path": self.geogrid_tbl_file,
127
+ "save_path": f"{get_wrf_workspace_path('wps')}/geogrid",
128
+ "save_name": "GEOGRID.TBL",
129
+ "is_data": False,
130
+ "is_output": False,
117
131
  }
118
132
  self.add_input_files(tbl_file)
119
133
 
120
134
  super().before_exec()
121
135
 
122
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
136
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
123
137
 
124
138
  # print debug logs
125
139
  logger.debug("Namelist settings of 'geogrid':")
126
- logger.debug(WRFRUNConfig.get_namelist("wps"))
140
+ logger.debug(WRFRUN.config.get_namelist("wps"))
127
141
 
128
142
  def after_exec(self):
129
- if not WRFRUNConfig.IS_IN_REPLAY:
143
+ if not WRFRUN.config.IS_IN_REPLAY:
130
144
  self.add_output_files(save_path=self._log_save_path, startswith="geogrid.log", outputs=NamelistName.WPS)
131
145
  self.add_output_files(save_path=self._output_save_path, startswith="geo_em")
132
146
 
133
147
  super().after_exec()
134
148
 
135
- logger.info(f"All geogrid output files have been copied to {WRFRUNConfig.parse_resource_uri(self._output_save_path)}")
149
+ logger.info(f"All geogrid output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
136
150
 
137
151
 
138
152
  class LinkGrib(ExecutableBase):
@@ -149,7 +163,11 @@ class LinkGrib(ExecutableBase):
149
163
  """
150
164
  self._link_grib_input_path = "./input_grib_data_dir"
151
165
 
152
- super().__init__(name="link_grib", cmd=["./link_grib.csh", f"{self._link_grib_input_path}/*", "."], work_path=WORKSPACE_MODEL_WPS)
166
+ super().__init__(
167
+ name="link_grib",
168
+ cmd=["./link_grib.csh", f"{self._link_grib_input_path}/*", "."],
169
+ work_path=get_wrf_workspace_path("wps"),
170
+ )
153
171
  self.grib_dir_path = grib_dir_path
154
172
 
155
173
  def generate_custom_config(self):
@@ -161,8 +179,7 @@ class LinkGrib(ExecutableBase):
161
179
  self.class_config["class_args"] = (self.grib_dir_path,)
162
180
 
163
181
  def before_exec(self):
164
- if not WRFRUNConfig.IS_IN_REPLAY:
165
-
182
+ if not WRFRUN.config.IS_IN_REPLAY:
166
183
  logger.debug(f"Input data are: {self.grib_dir_path}")
167
184
  _grib_dir_path = abspath(self.grib_dir_path)
168
185
 
@@ -170,16 +187,18 @@ class LinkGrib(ExecutableBase):
170
187
  logger.error(f"GRIB file directory not found: {_grib_dir_path}")
171
188
  raise FileNotFoundError(f"GRIB file directory not found: {_grib_dir_path}")
172
189
 
173
- save_path = f"{WORKSPACE_MODEL_WPS}/{self._link_grib_input_path}"
174
- save_path = WRFRUNConfig.parse_resource_uri(save_path)
190
+ save_path = f"{get_wrf_workspace_path('wps')}/{self._link_grib_input_path}"
191
+ save_path = WRFRUN.config.parse_resource_uri(save_path)
175
192
  if exists(save_path):
176
193
  rmtree(save_path)
177
194
 
178
195
  for _file in listdir(_grib_dir_path):
179
196
  _file_config: FileConfigDict = {
180
197
  "file_path": f"{_grib_dir_path}/{_file}",
181
- "save_path": f"{WORKSPACE_MODEL_WPS}/{self._link_grib_input_path}",
182
- "save_name": _file, "is_data": True, "is_output": False,
198
+ "save_path": f"{get_wrf_workspace_path('wps')}/{self._link_grib_input_path}",
199
+ "save_name": _file,
200
+ "is_data": True,
201
+ "is_output": False,
183
202
  }
184
203
  self.add_input_files(_file_config)
185
204
 
@@ -202,7 +221,7 @@ class UnGrib(ExecutableBase):
202
221
  Defaults to ``input_data_path`` set in user's config file.
203
222
  :type input_data_path: str
204
223
  """
205
- super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=WORKSPACE_MODEL_WPS)
224
+ super().__init__(name="ungrib", cmd="./ungrib.exe", work_path=get_wrf_workspace_path("wps"))
206
225
 
207
226
  self.vtable_file = vtable_file
208
227
  self.input_data_path = input_data_path
@@ -214,7 +233,7 @@ class UnGrib(ExecutableBase):
214
233
  Call :class:`LinkGrib` if needed.
215
234
  """
216
235
  if self.input_data_path is None:
217
- self.input_data_path = WRFRUNConfig.get_input_data_path()
236
+ self.input_data_path = WRFRUN.config.get_input_data_path()
218
237
 
219
238
  LinkGrib(self.input_data_path)()
220
239
 
@@ -239,53 +258,50 @@ class UnGrib(ExecutableBase):
239
258
  1. Namelist settings.
240
259
  2. Path of used VTable file.
241
260
  """
242
- self.custom_config.update(
243
- {
244
- "namelist": WRFRUNConfig.get_namelist("wps"),
245
- "vtable_file": self.vtable_file
246
- }
247
- )
261
+ self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wps"), "vtable_file": self.vtable_file})
248
262
 
249
263
  def load_custom_config(self):
250
264
  """
251
265
  Load custom configs.
252
266
  """
253
267
  self.vtable_file = self.custom_config["vtable_file"]
254
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
268
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
255
269
 
256
270
  def before_exec(self):
257
- WRFRUNConfig.check_wrfrun_context(True)
258
- WRFRUNConfig.WRFRUN_WORK_STATUS = "ungrib"
271
+ WRFRUN.config.check_wrfrun_context(True)
272
+ WRFRUN.config.WRFRUN_WORK_STATUS = "ungrib"
259
273
 
260
- if not WRFRUNConfig.IS_IN_REPLAY:
274
+ if not WRFRUN.config.IS_IN_REPLAY:
261
275
  if self.vtable_file is None:
262
276
  self.vtable_file = VtableFiles.ERA_PL
263
277
 
264
278
  _file_config: FileConfigDict = {
265
279
  "file_path": self.vtable_file,
266
- "save_path": WORKSPACE_MODEL_WPS,
280
+ "save_path": get_wrf_workspace_path("wps"),
267
281
  "save_name": "Vtable",
268
282
  "is_data": False,
269
- "is_output": False
283
+ "is_output": False,
270
284
  }
271
285
  self.add_input_files(_file_config)
272
286
 
273
287
  super().before_exec()
274
288
 
275
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
289
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
276
290
 
277
291
  # print debug logs
278
292
  logger.debug("Namelist settings of 'ungrib':")
279
- logger.debug(WRFRUNConfig.get_namelist("wps"))
293
+ logger.debug(WRFRUN.config.get_namelist("wps"))
280
294
 
281
295
  def after_exec(self):
282
- if not WRFRUNConfig.IS_IN_REPLAY:
283
- self.add_output_files(output_dir=get_ungrib_out_dir_path(), save_path=self._output_save_path, startswith=get_ungrib_out_prefix())
296
+ if not WRFRUN.config.IS_IN_REPLAY:
297
+ self.add_output_files(
298
+ output_dir=get_ungrib_out_dir_path(), save_path=self._output_save_path, startswith=get_ungrib_out_prefix()
299
+ )
284
300
  self.add_output_files(save_path=self._log_save_path, outputs=["ungrib.log", "namelist.wps"])
285
301
 
286
302
  super().after_exec()
287
303
 
288
- logger.info(f"All ungrib output files have been copied to {WRFRUNConfig.parse_resource_uri(self._output_save_path)}")
304
+ logger.info(f"All ungrib output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
289
305
 
290
306
  def __call__(self):
291
307
  self.call_link_grib()
@@ -298,7 +314,9 @@ class MetGrid(ExecutableBase):
298
314
  ``Executable`` of "metgrid.exe".
299
315
  """
300
316
 
301
- def __init__(self, geogrid_data_path: Optional[str] = None, ungrib_data_path: Optional[str] = None, core_num: Optional[int] = None):
317
+ def __init__(
318
+ self, geogrid_data_path: Optional[str] = None, ungrib_data_path: Optional[str] = None, core_num: Optional[int] = None
319
+ ):
302
320
  """
303
321
  ``Executable`` of "metgrid.exe".
304
322
 
@@ -312,7 +330,7 @@ class MetGrid(ExecutableBase):
312
330
  :type core_num: int
313
331
  """
314
332
  if isinstance(core_num, int) and core_num <= 0:
315
- logger.warning(f"`core_num` should be greater than 0")
333
+ logger.warning("`core_num` should be greater than 0")
316
334
  core_num = None
317
335
 
318
336
  if core_num is None:
@@ -325,7 +343,14 @@ class MetGrid(ExecutableBase):
325
343
  mpi_cmd = "mpirun"
326
344
  mpi_core_num = core_num
327
345
 
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)
346
+ super().__init__(
347
+ name="metgrid",
348
+ cmd="./metgrid.exe",
349
+ work_path=get_wrf_workspace_path("wps"),
350
+ mpi_use=mpi_use,
351
+ mpi_cmd=mpi_cmd,
352
+ mpi_core_num=mpi_core_num,
353
+ )
329
354
 
330
355
  self.geogrid_data_path = geogrid_data_path
331
356
  self.ungrib_data_path = ungrib_data_path
@@ -341,7 +366,9 @@ class MetGrid(ExecutableBase):
341
366
  :rtype: MetGrid
342
367
  """
343
368
  if isinstance(fg_names, str):
344
- fg_names = [fg_names, ]
369
+ fg_names = [
370
+ fg_names,
371
+ ]
345
372
  fg_names = [basename(x) for x in fg_names]
346
373
  set_metgrid_fg_names(fg_names)
347
374
  return self
@@ -358,7 +385,7 @@ class MetGrid(ExecutableBase):
358
385
  {
359
386
  "geogrid_data_path": self.geogrid_data_path,
360
387
  "ungrib_data_path": self.ungrib_data_path,
361
- "namelist": WRFRUNConfig.get_namelist("wps"),
388
+ "namelist": WRFRUN.config.get_namelist("wps"),
362
389
  }
363
390
  )
364
391
 
@@ -368,50 +395,56 @@ class MetGrid(ExecutableBase):
368
395
  """
369
396
  self.geogrid_data_path = self.custom_config["geogrid_data_path"]
370
397
  self.ungrib_data_path = self.custom_config["ungrib_data_path"]
371
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wps")
398
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wps")
372
399
 
373
400
  def before_exec(self):
374
- WRFRUNConfig.check_wrfrun_context(True)
375
- WRFRUNConfig.WRFRUN_WORK_STATUS = "metgrid"
401
+ WRFRUN.config.check_wrfrun_context(True)
402
+ WRFRUN.config.WRFRUN_WORK_STATUS = "metgrid"
376
403
 
377
- if not WRFRUNConfig.IS_IN_REPLAY and not WRFRUNConfig.FAKE_SIMULATION_MODE:
404
+ if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
378
405
  # check input of metgrid.exe
379
406
  # try to search input files in the output path if workspace is clear.
380
- file_list = listdir(WRFRUNConfig.parse_resource_uri(WORKSPACE_MODEL_WPS))
407
+ file_list = listdir(WRFRUN.config.parse_resource_uri(get_wrf_workspace_path("wps")))
381
408
 
382
409
  if "geo_em.d01.nc" not in file_list:
383
-
384
410
  if self.geogrid_data_path is None:
385
- self.geogrid_data_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/geogrid"
386
- geogrid_data_path = WRFRUNConfig.parse_resource_uri(self.geogrid_data_path)
411
+ self.geogrid_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/geogrid"
412
+ geogrid_data_path = WRFRUN.config.parse_resource_uri(self.geogrid_data_path)
387
413
 
388
414
  if not exists(geogrid_data_path) or "geo_em.d01.nc" not in listdir(geogrid_data_path):
389
- logger.error(f"Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid")
390
- raise FileNotFoundError(f"Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid")
415
+ logger.error(
416
+ "Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
417
+ )
418
+ raise FileNotFoundError(
419
+ "Can't find geogrid outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
420
+ )
391
421
 
392
422
  else:
393
423
  geogrid_file_list = [x for x in listdir(geogrid_data_path) if x.startswith("geo_em.d")]
394
424
  for _file in geogrid_file_list:
395
425
  _file_config = {
396
426
  "file_path": f"{self.geogrid_data_path}/{_file}",
397
- "save_path": WORKSPACE_MODEL_WPS,
427
+ "save_path": get_wrf_workspace_path("wps"),
398
428
  "save_name": _file,
399
429
  "is_data": True,
400
- "is_output": True
430
+ "is_output": True,
401
431
  }
402
432
  self.add_input_files(_file_config)
403
433
 
404
- ungrib_output_dir = WRFRUNConfig.parse_resource_uri(get_ungrib_out_dir_path())
434
+ ungrib_output_dir = WRFRUN.config.parse_resource_uri(get_ungrib_out_dir_path())
405
435
  if basename(ungrib_output_dir) not in file_list or len(listdir(ungrib_output_dir)) == 0:
406
-
407
436
  if self.ungrib_data_path is None:
408
- self.ungrib_data_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/ungrib"
437
+ self.ungrib_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/ungrib"
409
438
 
410
- ungrib_data_path = WRFRUNConfig.parse_resource_uri(self.ungrib_data_path)
439
+ ungrib_data_path = WRFRUN.config.parse_resource_uri(self.ungrib_data_path)
411
440
 
412
441
  if not exists(ungrib_data_path) or len(listdir(ungrib_data_path)) == 0:
413
- logger.error(f"Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid")
414
- raise FileNotFoundError(f"Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid")
442
+ logger.error(
443
+ "Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
444
+ )
445
+ raise FileNotFoundError(
446
+ "Can't find ungrib outputs in WPS_WORK_PATH and your outputs directory, which is essential to run metgrid"
447
+ )
415
448
 
416
449
  else:
417
450
  ungrib_file_list = [x for x in listdir(ungrib_data_path)]
@@ -421,22 +454,26 @@ class MetGrid(ExecutableBase):
421
454
  "save_path": get_ungrib_out_dir_path(),
422
455
  "save_name": _file,
423
456
  "is_data": True,
424
- "is_output": True
457
+ "is_output": True,
425
458
  }
426
459
  self.add_input_files(_file_config)
427
460
 
428
461
  super().before_exec()
429
462
 
430
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WPS}/{NamelistName.WPS}", "wps")
463
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wps')}/{NamelistName.WPS}", "wps")
464
+
465
+ # print debug logs
466
+ logger.debug("Namelist settings of 'metgrid':")
467
+ logger.debug(WRFRUN.config.get_namelist("wps"))
431
468
 
432
469
  def after_exec(self):
433
- if not WRFRUNConfig.IS_IN_REPLAY:
470
+ if not WRFRUN.config.IS_IN_REPLAY:
434
471
  self.add_output_files(save_path=self._log_save_path, startswith="metgrid.log", outputs="namelist.wps")
435
472
  self.add_output_files(save_path=self._output_save_path, startswith="met_em")
436
473
 
437
474
  super().after_exec()
438
475
 
439
- logger.info(f"All metgrid output files have been copied to {WRFRUNConfig.parse_resource_uri(self._output_save_path)}")
476
+ logger.info(f"All metgrid output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
440
477
 
441
478
 
442
479
  class Real(ExecutableBase):
@@ -455,7 +492,7 @@ class Real(ExecutableBase):
455
492
  :type core_num: int
456
493
  """
457
494
  if isinstance(core_num, int) and core_num <= 0:
458
- logger.warning(f"`core_num` should be greater than 0")
495
+ logger.warning("`core_num` should be greater than 0")
459
496
  core_num = None
460
497
 
461
498
  if core_num is None:
@@ -470,7 +507,14 @@ class Real(ExecutableBase):
470
507
 
471
508
  _check_and_prepare_namelist()
472
509
 
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)
510
+ super().__init__(
511
+ name="real",
512
+ cmd="./real.exe",
513
+ work_path=get_wrf_workspace_path("wrf"),
514
+ mpi_use=mpi_use,
515
+ mpi_cmd=mpi_cmd,
516
+ mpi_core_num=mpi_core_num,
517
+ )
474
518
 
475
519
  self.metgrid_data_path = metgrid_data_path
476
520
 
@@ -482,54 +526,53 @@ class Real(ExecutableBase):
482
526
  2. Directory path of :class:`MetGrid` outputs.
483
527
  """
484
528
  self.custom_config["metgrid_data_path"] = self.metgrid_data_path
485
- self.custom_config.update(
486
- {
487
- "namelist": WRFRUNConfig.get_namelist("wrf"),
488
- "metgrid_data_path": self.metgrid_data_path
489
- }
490
- )
529
+ self.custom_config.update({"namelist": WRFRUN.config.get_namelist("wrf"), "metgrid_data_path": self.metgrid_data_path})
491
530
 
492
531
  def load_custom_config(self):
493
532
  """
494
533
  Load custom configs.
495
534
  """
496
535
  self.metgrid_data_path = self.custom_config["metgrid_data_path"]
497
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
536
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
498
537
 
499
538
  def before_exec(self):
500
- WRFRUNConfig.check_wrfrun_context(True)
501
- WRFRUNConfig.WRFRUN_WORK_STATUS = "real"
539
+ WRFRUN.config.check_wrfrun_context(True)
540
+ WRFRUN.config.WRFRUN_WORK_STATUS = "real"
502
541
 
503
- if not WRFRUNConfig.IS_IN_REPLAY and not WRFRUNConfig.FAKE_SIMULATION_MODE:
542
+ if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
504
543
  if self.metgrid_data_path is None:
505
- self.metgrid_data_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/metgrid"
544
+ self.metgrid_data_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/metgrid"
506
545
 
507
- metgrid_data_path = WRFRUNConfig.parse_resource_uri(self.metgrid_data_path)
546
+ metgrid_data_path = WRFRUN.config.parse_resource_uri(self.metgrid_data_path)
508
547
  reconcile_namelist_metgrid(metgrid_data_path)
509
548
 
510
549
  file_list = [x for x in listdir(metgrid_data_path) if x.startswith("met_em")]
511
550
  for _file in file_list:
512
551
  _file_config: FileConfigDict = {
513
552
  "file_path": f"{self.metgrid_data_path}/{_file}",
514
- "save_path": WORKSPACE_MODEL_WRF,
553
+ "save_path": get_wrf_workspace_path("wrf"),
515
554
  "save_name": _file,
516
555
  "is_data": True,
517
- "is_output": True
556
+ "is_output": True,
518
557
  }
519
558
  self.add_input_files(_file_config)
520
559
 
521
560
  super().before_exec()
522
561
 
523
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
562
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
563
+
564
+ # print debug logs
565
+ logger.debug("Namelist settings of 'real':")
566
+ logger.debug(WRFRUN.config.get_namelist("wrf"))
524
567
 
525
568
  def after_exec(self):
526
- if not WRFRUNConfig.IS_IN_REPLAY:
569
+ if not WRFRUN.config.IS_IN_REPLAY:
527
570
  self.add_output_files(save_path=self._output_save_path, startswith=("wrfbdy", "wrfinput", "wrflow"))
528
571
  self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
529
572
 
530
573
  super().after_exec()
531
574
 
532
- logger.info(f"All real output files have been copied to {WRFRUNConfig.parse_resource_uri(self._output_save_path)}")
575
+ logger.info(f"All real output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
533
576
 
534
577
 
535
578
  class WRF(ExecutableBase):
@@ -537,7 +580,13 @@ class WRF(ExecutableBase):
537
580
  ``Executable`` of "wrf.exe".
538
581
  """
539
582
 
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):
583
+ def __init__(
584
+ self,
585
+ input_file_dir_path: Optional[str] = None,
586
+ restart_file_dir_path: Optional[str] = None,
587
+ save_restarts=False,
588
+ core_num: Optional[int] = None,
589
+ ):
541
590
  """
542
591
  ``Executable`` of "wrf.exe"
543
592
 
@@ -551,7 +600,7 @@ class WRF(ExecutableBase):
551
600
  :type core_num: int
552
601
  """
553
602
  if isinstance(core_num, int) and core_num <= 0:
554
- logger.warning(f"`core_num` should be greater than 0")
603
+ logger.warning("`core_num` should be greater than 0")
555
604
  core_num = None
556
605
 
557
606
  if core_num is None:
@@ -566,7 +615,14 @@ class WRF(ExecutableBase):
566
615
 
567
616
  _check_and_prepare_namelist()
568
617
 
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)
618
+ super().__init__(
619
+ name="wrf",
620
+ cmd="./wrf.exe",
621
+ work_path=get_wrf_workspace_path("wrf"),
622
+ mpi_use=mpi_use,
623
+ mpi_cmd=mpi_cmd,
624
+ mpi_core_num=mpi_core_num,
625
+ )
570
626
 
571
627
  self.input_file_dir_path = input_file_dir_path
572
628
  self.restart_file_dir_path = restart_file_dir_path
@@ -584,7 +640,7 @@ class WRF(ExecutableBase):
584
640
  {
585
641
  "input_file_dir_path": self.input_file_dir_path,
586
642
  "restart_file_dir_path": self.restart_file_dir_path,
587
- "namelist": WRFRUNConfig.get_namelist("wrf")
643
+ "namelist": WRFRUN.config.get_namelist("wrf"),
588
644
  }
589
645
  )
590
646
 
@@ -594,30 +650,30 @@ class WRF(ExecutableBase):
594
650
  """
595
651
  self.input_file_dir_path = self.custom_config["input_file_dir_path"]
596
652
  self.restart_file_dir_path = self.custom_config["restart_file_dir_path"]
597
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "wrf")
653
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
598
654
 
599
655
  def before_exec(self):
600
- WRFRUNConfig.check_wrfrun_context(True)
656
+ WRFRUN.config.check_wrfrun_context(True)
601
657
  # help wrfrun to make sure the input file is from real or ndown.
602
- last_work_status = WRFRUNConfig.WRFRUN_WORK_STATUS
658
+ last_work_status = WRFRUN.config.WRFRUN_WORK_STATUS
603
659
  if last_work_status not in ["real", "ndown"]:
604
660
  last_work_status = ""
605
- WRFRUNConfig.WRFRUN_WORK_STATUS = "wrf"
661
+ WRFRUN.config.WRFRUN_WORK_STATUS = "wrf"
606
662
 
607
- if not WRFRUNConfig.IS_IN_REPLAY and not WRFRUNConfig.FAKE_SIMULATION_MODE:
663
+ if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
608
664
  if self.input_file_dir_path is None:
609
665
  if last_work_status == "":
610
666
  # assume we already have outputs from real.exe.
611
- self.input_file_dir_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/real"
667
+ self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
612
668
  is_output = False
613
669
  else:
614
- self.input_file_dir_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/{last_work_status}"
670
+ self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/{last_work_status}"
615
671
  is_output = True
616
672
 
617
673
  else:
618
674
  is_output = False
619
675
 
620
- input_file_dir_path = WRFRUNConfig.parse_resource_uri(self.input_file_dir_path)
676
+ input_file_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
621
677
 
622
678
  if exists(input_file_dir_path):
623
679
  file_list = [x for x in listdir(input_file_dir_path) if x != "logs"]
@@ -625,19 +681,19 @@ class WRF(ExecutableBase):
625
681
  for _file in file_list:
626
682
  _file_config: FileConfigDict = {
627
683
  "file_path": f"{self.input_file_dir_path}/{_file}",
628
- "save_path": WORKSPACE_MODEL_WRF,
684
+ "save_path": get_wrf_workspace_path("wrf"),
629
685
  "save_name": _file,
630
686
  "is_data": True,
631
- "is_output": is_output
687
+ "is_output": is_output,
632
688
  }
633
689
  self.add_input_files(_file_config)
634
690
 
635
- if WRFRUNConfig.get_model_config("wrf")["restart_mode"]:
691
+ if WRFRUN.config.get_model_config("wrf")["restart_mode"]:
636
692
  if self.restart_file_dir_path is None:
637
693
  logger.error("You need to specify the restart file if you want to restart WRF.")
638
694
  raise InputFileError("You need to specify the restart file if you want to restart WRF.")
639
695
 
640
- restart_file_dir_path = WRFRUNConfig.parse_resource_uri(self.restart_file_dir_path)
696
+ restart_file_dir_path = WRFRUN.config.parse_resource_uri(self.restart_file_dir_path)
641
697
 
642
698
  if not exists(restart_file_dir_path):
643
699
  logger.error(f"Restart files not found: {restart_file_dir_path}")
@@ -647,19 +703,23 @@ class WRF(ExecutableBase):
647
703
  for _file in file_list:
648
704
  _file_config: FileConfigDict = {
649
705
  "file_path": f"{self.restart_file_dir_path}/{_file}",
650
- "save_path": WORKSPACE_MODEL_WRF,
706
+ "save_path": get_wrf_workspace_path("wrf"),
651
707
  "save_name": _file,
652
708
  "is_data": True,
653
- "is_output": False
709
+ "is_output": False,
654
710
  }
655
711
  self.add_input_files(_file_config)
656
712
 
657
713
  super().before_exec()
658
714
 
659
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
715
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
716
+
717
+ # print debug logs
718
+ logger.debug("Namelist settings of 'wrf':")
719
+ logger.debug(WRFRUN.config.get_namelist("wrf"))
660
720
 
661
721
  def after_exec(self):
662
- if not WRFRUNConfig.IS_IN_REPLAY:
722
+ if not WRFRUN.config.IS_IN_REPLAY:
663
723
  self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
664
724
  self.add_output_files(save_path=self._output_save_path, startswith="wrfout")
665
725
  if self.save_restarts:
@@ -668,7 +728,7 @@ class WRF(ExecutableBase):
668
728
 
669
729
  super().after_exec()
670
730
 
671
- logger.info(f"All wrf output files have been copied to {WRFRUNConfig.parse_resource_uri(self._output_save_path)}")
731
+ logger.info(f"All wrf output files have been copied to {WRFRUN.config.parse_resource_uri(self._output_save_path)}")
672
732
 
673
733
 
674
734
  class DFI(ExecutableBase):
@@ -688,7 +748,7 @@ class DFI(ExecutableBase):
688
748
  :type core_num: int
689
749
  """
690
750
  if isinstance(core_num, int) and core_num <= 0:
691
- logger.warning(f"`core_num` should be greater than 0")
751
+ logger.warning("`core_num` should be greater than 0")
692
752
  core_num = None
693
753
 
694
754
  if core_num is None:
@@ -701,7 +761,14 @@ class DFI(ExecutableBase):
701
761
  mpi_cmd = "mpirun"
702
762
  mpi_core_num = core_num
703
763
 
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)
764
+ super().__init__(
765
+ name="dfi",
766
+ cmd="./wrf.exe",
767
+ work_path=get_wrf_workspace_path("wrf"),
768
+ mpi_use=mpi_use,
769
+ mpi_cmd=mpi_cmd,
770
+ mpi_core_num=mpi_core_num,
771
+ )
705
772
 
706
773
  self.input_file_dir_path = input_file_dir_path
707
774
  self.update_real_output = update_real_output
@@ -718,7 +785,7 @@ class DFI(ExecutableBase):
718
785
  {
719
786
  "input_file_dir_path": self.input_file_dir_path,
720
787
  "update_real_output": self.update_real_output,
721
- "namelist": WRFRUNConfig.get_namelist("dfi")
788
+ "namelist": WRFRUN.config.get_namelist("dfi"),
722
789
  }
723
790
  )
724
791
 
@@ -729,25 +796,25 @@ class DFI(ExecutableBase):
729
796
  self.input_file_dir_path = self.custom_config["input_file_dir_path"]
730
797
  self.update_real_output = self.custom_config["update_real_output"]
731
798
 
732
- if not WRFRUNConfig.register_custom_namelist_id("dfi"):
799
+ if not WRFRUN.config.register_namelist_id("dfi"):
733
800
  logger.error("Can't register namelist for DFI.")
734
801
  raise NamelistIDError("Can't register namelist for DFI.")
735
- WRFRUNConfig.update_namelist(self.custom_config["namelist"], "dfi")
802
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "dfi")
736
803
 
737
804
  def before_exec(self):
738
- WRFRUNConfig.check_wrfrun_context(True)
739
- WRFRUNConfig.WRFRUN_WORK_STATUS = "dfi"
805
+ WRFRUN.config.check_wrfrun_context(True)
806
+ WRFRUN.config.WRFRUN_WORK_STATUS = "dfi"
740
807
 
741
- if not WRFRUNConfig.IS_IN_REPLAY and not WRFRUNConfig.FAKE_SIMULATION_MODE:
808
+ if not WRFRUN.config.IS_IN_REPLAY and not WRFRUN.config.FAKE_SIMULATION_MODE:
742
809
  # prepare config
743
810
  if self.input_file_dir_path is None:
744
- self.input_file_dir_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/real"
811
+ self.input_file_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
745
812
  is_output = True
746
813
 
747
814
  else:
748
815
  is_output = False
749
816
 
750
- input_file_dir_path = WRFRUNConfig.parse_resource_uri(self.input_file_dir_path)
817
+ input_file_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
751
818
 
752
819
  if exists(input_file_dir_path):
753
820
  file_list = [x for x in listdir(input_file_dir_path) if x != "logs"]
@@ -755,36 +822,38 @@ class DFI(ExecutableBase):
755
822
  for _file in file_list:
756
823
  _file_config: FileConfigDict = {
757
824
  "file_path": f"{self.input_file_dir_path}/{_file}",
758
- "save_path": WORKSPACE_MODEL_WRF,
825
+ "save_path": get_wrf_workspace_path("wrf"),
759
826
  "save_name": _file,
760
827
  "is_data": True,
761
- "is_output": is_output
828
+ "is_output": is_output,
762
829
  }
763
830
  self.add_input_files(_file_config)
764
831
 
765
- if not WRFRUNConfig.register_custom_namelist_id("dfi"):
832
+ if not WRFRUN.config.register_namelist_id("dfi"):
766
833
  logger.error("Can't register namelist for DFI.")
767
834
  raise NamelistIDError("Can't register namelist for DFI.")
768
835
 
769
836
  prepare_dfi_namelist()
770
837
 
771
838
  super().before_exec()
772
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "dfi")
839
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "dfi")
773
840
 
774
841
  def after_exec(self):
775
- if not WRFRUNConfig.IS_IN_REPLAY:
842
+ if not WRFRUN.config.IS_IN_REPLAY:
776
843
  self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
777
844
  self.add_output_files(save_path=self._output_save_path, startswith="wrfinput_initialized_")
778
845
 
779
846
  super().after_exec()
780
847
 
781
- parsed_output_save_path = WRFRUNConfig.parse_resource_uri(self._output_save_path)
782
- if self.update_real_output and not WRFRUNConfig.FAKE_SIMULATION_MODE:
783
- real_dir_path = WRFRUNConfig.parse_resource_uri(self.input_file_dir_path)
848
+ parsed_output_save_path = WRFRUN.config.parse_resource_uri(self._output_save_path)
849
+ if self.update_real_output and not WRFRUN.config.FAKE_SIMULATION_MODE:
850
+ real_dir_path = WRFRUN.config.parse_resource_uri(self.input_file_dir_path)
784
851
 
785
852
  move(f"{real_dir_path}/wrfinput_d01", f"{real_dir_path}/wrfinput_d01_before_dfi")
786
853
  copyfile(f"{parsed_output_save_path}/wrfinput_initialized_d01", f"{real_dir_path}/wrfinput_d01")
787
- logger.info(f"Replace real.exe output 'wrfinput_d01' with outputs, old file has been renamed as 'wrfinput_d01_before_dfi'")
854
+ logger.info(
855
+ "Replace real.exe output 'wrfinput_d01' with outputs, old file has been renamed as 'wrfinput_d01_before_dfi'"
856
+ )
788
857
 
789
858
  logger.info(f"All DFI output files have been copied to {parsed_output_save_path}")
790
859
 
@@ -794,7 +863,13 @@ class NDown(ExecutableBase):
794
863
  ``Executable`` of "ndown.exe".
795
864
  """
796
865
 
797
- def __init__(self, wrfout_file_path: str, real_output_dir_path: Optional[str] = None, update_namelist=True, core_num: Optional[int] = None):
866
+ def __init__(
867
+ self,
868
+ wrfout_file_path: str,
869
+ real_output_dir_path: Optional[str] = None,
870
+ update_namelist=True,
871
+ core_num: Optional[int] = None,
872
+ ):
798
873
  """
799
874
  ``Executable`` of "ndown.exe".
800
875
 
@@ -808,7 +883,7 @@ class NDown(ExecutableBase):
808
883
  :type core_num: int
809
884
  """
810
885
  if isinstance(core_num, int) and core_num <= 0:
811
- logger.warning(f"`core_num` should be greater than 0")
886
+ logger.warning("`core_num` should be greater than 0")
812
887
  core_num = None
813
888
 
814
889
  if core_num is None:
@@ -823,7 +898,14 @@ class NDown(ExecutableBase):
823
898
 
824
899
  _check_and_prepare_namelist()
825
900
 
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)
901
+ super().__init__(
902
+ name="ndown",
903
+ cmd="./ndown.exe",
904
+ work_path=get_wrf_workspace_path("wrf"),
905
+ mpi_use=mpi_use,
906
+ mpi_cmd=mpi_cmd,
907
+ mpi_core_num=mpi_core_num,
908
+ )
827
909
 
828
910
  self.wrfout_file_path = wrfout_file_path
829
911
  self.real_output_dir_path = real_output_dir_path
@@ -843,7 +925,7 @@ class NDown(ExecutableBase):
843
925
  {
844
926
  "real_output_dir_path": self.real_output_dir_path,
845
927
  "update_namelist": self.update_namelist,
846
- "namelist": WRFRUNConfig.get_namelist("wrf"),
928
+ "namelist": WRFRUN.config.get_namelist("wrf"),
847
929
  }
848
930
  )
849
931
 
@@ -853,18 +935,18 @@ class NDown(ExecutableBase):
853
935
  """
854
936
  self.real_output_dir_path = self.custom_config["real_output_dir_path"]
855
937
  self.update_namelist = self.custom_config["update_namelist"]
856
- WRFRUNConfig.update_namelist(self.custom_config["namelist"])
938
+ WRFRUN.config.update_namelist(self.custom_config["namelist"], "wrf")
857
939
 
858
940
  def before_exec(self):
859
- WRFRUNConfig.check_wrfrun_context(True)
860
- WRFRUNConfig.WRFRUN_WORK_STATUS = "ndown"
941
+ WRFRUN.config.check_wrfrun_context(True)
942
+ WRFRUN.config.WRFRUN_WORK_STATUS = "ndown"
861
943
 
862
944
  # we need to make sure time_control.io_form_auxinput2 is 2.
863
945
  # which means the format of input stream 2 is NetCDF.
864
- WRFRUNConfig.update_namelist({"time_control": {"io_form_auxinput2": 2}}, "wrf")
946
+ WRFRUN.config.update_namelist({"time_control": {"io_form_auxinput2": 2}}, "wrf")
865
947
 
866
948
  if self.real_output_dir_path is None:
867
- self.real_output_dir_path = f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/real"
949
+ self.real_output_dir_path = f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real"
868
950
  is_output = True
869
951
 
870
952
  else:
@@ -872,35 +954,39 @@ class NDown(ExecutableBase):
872
954
 
873
955
  wrfndi_file_config: FileConfigDict = {
874
956
  "file_path": f"{self.real_output_dir_path}/wrfinput_d02",
875
- "save_path": WORKSPACE_MODEL_WRF,
957
+ "save_path": get_wrf_workspace_path("wrf"),
876
958
  "save_name": "wrfndi_d02",
877
959
  "is_data": True,
878
- "is_output": is_output
960
+ "is_output": is_output,
879
961
  }
880
962
  wrfout_file_config: FileConfigDict = {
881
963
  "file_path": self.wrfout_file_path,
882
- "save_path": WORKSPACE_MODEL_WRF,
964
+ "save_path": get_wrf_workspace_path("wrf"),
883
965
  "save_name": "wrfout_d01",
884
966
  "is_data": True,
885
- "is_output": False
967
+ "is_output": False,
886
968
  }
887
969
 
888
970
  self.add_input_files([wrfndi_file_config, wrfout_file_config])
889
971
 
890
972
  super().before_exec()
891
973
 
892
- WRFRUNConfig.write_namelist(f"{WORKSPACE_MODEL_WRF}/{NamelistName.WRF}", "wrf")
974
+ WRFRUN.config.write_namelist(f"{get_wrf_workspace_path('wrf')}/{NamelistName.WRF}", "wrf")
893
975
 
894
976
  def after_exec(self):
895
977
  self.add_output_files(save_path=self._log_save_path, startswith="rsl.", outputs="namelist.input")
896
978
  self.add_output_files(save_path=self._output_save_path, outputs=["wrfinput_d02", "wrfbdy_d02"])
897
979
  # also save other outputs of real.exe, so WRF can directly use them.
898
- self.add_output_files(output_dir=f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/real", save_path=self._output_save_path,
899
- startswith="wrflowinp_", no_file_error=False)
980
+ self.add_output_files(
981
+ output_dir=f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/real",
982
+ save_path=self._output_save_path,
983
+ startswith="wrflowinp_",
984
+ no_file_error=False,
985
+ )
900
986
 
901
987
  super().after_exec()
902
988
 
903
- parsed_output_save_path = WRFRUNConfig.parse_resource_uri(self._output_save_path)
989
+ parsed_output_save_path = WRFRUN.config.parse_resource_uri(self._output_save_path)
904
990
 
905
991
  move(f"{parsed_output_save_path}/wrfinput_d02", f"{parsed_output_save_path}/wrfinput_d01")
906
992
  move(f"{parsed_output_save_path}/wrfbdy_d02", f"{parsed_output_save_path}/wrfbdy_d01")
@@ -911,11 +997,22 @@ class NDown(ExecutableBase):
911
997
  process_after_ndown()
912
998
 
913
999
 
914
- class_list = [GeoGrid, LinkGrib, UnGrib, MetGrid, Real, WRF, NDown]
915
- class_id_list = ["geogrid", "link_grib", "ungrib", "metgrid", "real", "wrf", "ndown"]
1000
+ def _exec_register_func(exec_db: ExecutableDB):
1001
+ """
1002
+ Function to register ``Executable``.
1003
+
1004
+ :param exec_db: ``ExecutableDB`` instance.
1005
+ :type exec_db: ExecutableDB
1006
+ """
1007
+ class_list = [GeoGrid, LinkGrib, UnGrib, MetGrid, Real, WRF, NDown]
1008
+ class_id_list = ["geogrid", "link_grib", "ungrib", "metgrid", "real", "wrf", "ndown"]
1009
+
1010
+ for _class, _id in zip(class_list, class_id_list):
1011
+ if not exec_db.is_registered(_id):
1012
+ exec_db.register_exec(_id, _class)
1013
+
1014
+
1015
+ WRFRUN.set_exec_db_register_func(_exec_register_func)
916
1016
 
917
- for _class, _id in zip(class_list, class_id_list):
918
- if not WRFRUNExecDB.is_registered(_id):
919
- WRFRUNExecDB.register_exec(_id, _class)
920
1017
 
921
1018
  __all__ = ["GeoGrid", "LinkGrib", "UnGrib", "MetGrid", "Real", "WRF", "DFI", "NDown"]