wrfrun 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. wrfrun/__init__.py +8 -3
  2. wrfrun/cli.py +69 -29
  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 +132 -406
  11. wrfrun/core/core.py +196 -0
  12. wrfrun/core/error.py +28 -2
  13. wrfrun/core/replay.py +10 -96
  14. wrfrun/core/server.py +52 -27
  15. wrfrun/core/type.py +171 -0
  16. wrfrun/data.py +304 -139
  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 +4 -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 -119
  30. wrfrun/model/type.py +116 -0
  31. wrfrun/model/utils.py +9 -20
  32. wrfrun/model/wrf/__init__.py +4 -9
  33. wrfrun/model/wrf/core.py +246 -161
  34. wrfrun/model/wrf/exec_wrap.py +13 -12
  35. wrfrun/model/wrf/geodata.py +116 -100
  36. wrfrun/model/wrf/log.py +103 -0
  37. wrfrun/model/wrf/namelist.py +90 -73
  38. wrfrun/model/wrf/plot.py +102 -0
  39. wrfrun/model/wrf/scheme.py +108 -52
  40. wrfrun/model/wrf/utils.py +39 -25
  41. wrfrun/model/wrf/vtable.py +35 -3
  42. wrfrun/plot/__init__.py +20 -0
  43. wrfrun/plot/wps.py +90 -73
  44. wrfrun/res/__init__.py +103 -5
  45. wrfrun/res/config/config.template.toml +8 -0
  46. wrfrun/res/config/palm.template.toml +23 -0
  47. wrfrun/run.py +105 -77
  48. wrfrun/scheduler/__init__.py +1 -0
  49. wrfrun/scheduler/lsf.py +3 -2
  50. wrfrun/scheduler/pbs.py +3 -2
  51. wrfrun/scheduler/script.py +17 -5
  52. wrfrun/scheduler/slurm.py +3 -2
  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 +20 -12
  57. wrfrun/workspace/palm.py +137 -0
  58. wrfrun/workspace/wrf.py +16 -15
  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 -923
  62. wrfrun/model/base.py +0 -14
  63. wrfrun-0.2.0.dist-info/METADATA +0 -68
  64. wrfrun-0.2.0.dist-info/RECORD +0 -62
  65. {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
  66. {wrfrun-0.2.0.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/run.py CHANGED
@@ -1,18 +1,58 @@
1
1
  """
2
- ``wrfrun.run`` module.
2
+ wrfrun.run
3
+ ##########
4
+
5
+ .. autosummary::
6
+ :toctree: generated/
7
+
8
+ confirm_model_area
9
+ WRFRun
10
+
11
+ This module defines class and function used by ``wrfrun`` to run simulations.
12
+
13
+ Use ``WRFRun`` to control simulations better
14
+ ********************************************
15
+
16
+ :class:`WRFRun` provides many useful features:
17
+
18
+ * Set log files.
19
+ * Load config and namelist from files.
20
+ * Clear and prepare ``wrfrun`` workspace.
21
+ * Download background data from ERA5.
22
+ * Commit simulation to job schedulers.
23
+ * Record and replay simulations.
24
+ * Start socket server.
25
+
26
+ Though you can do same things manually, why bother yourself while :class:`WRFRun` is easy to use:
27
+
28
+ .. code-block:: python
29
+ :caption: main.py
30
+
31
+ from wrfrun.run import WRFRun
32
+
33
+ config_file = "./config.toml"
34
+
35
+ with WRFRun(config_file) as wrf_run:
36
+ # do something
37
+ ...
3
38
  """
4
39
 
5
40
  import sys
6
41
  import threading
42
+ from collections.abc import Generator
7
43
  from os.path import abspath, dirname
8
44
  from typing import Optional, Tuple, Union
9
45
 
10
- from .core import ExecConfigRecorder, WRFRUNConfig, init_wrfrun_config, WRFRunBasicError, WRFRunServer, WRFRunServerHandler, replay_config_generator, stop_server
46
+ from wrfrun.core.base import ExecutableBase
47
+
48
+ from .core import WRFRunBasicError, WRFRunServer, WRFRunServerHandler, call_subprocess, replay_config_generator, stop_server
49
+ from .core._record import ExecutableRecorder
50
+ from .core.core import WRFRUN
11
51
  from .data import prepare_wps_input_data
52
+ from .log import logger, logger_add_file_handler
12
53
  from .model import clear_model_logs, generate_domain_area
13
54
  from .scheduler import in_job_scheduler, prepare_scheduler_script
14
- from .utils import call_subprocess, logger, logger_add_file_handler
15
- from .workspace import prepare_workspace, check_workspace
55
+ from .workspace import check_workspace, prepare_workspace
16
56
 
17
57
 
18
58
  def confirm_model_area():
@@ -20,17 +60,17 @@ def confirm_model_area():
20
60
  Ask user to check domain area.
21
61
 
22
62
  """
23
- generate_domain_area()
63
+ flag = generate_domain_area()
24
64
 
25
- if not in_job_scheduler():
65
+ if not in_job_scheduler() and flag:
26
66
  # ask user
27
- logger.warning(f"Check the domain image, is it right?")
67
+ logger.warning("Check the domain image, is it right?")
28
68
  answer = input("Is it right? [y/N]: ")
29
69
 
30
70
  answer = answer.lower()
31
71
 
32
72
  if answer not in ["y", "yes"]:
33
- logger.error(f"Change your domain setting and run again")
73
+ logger.error("Change your domain setting and run again")
34
74
  exit(1)
35
75
 
36
76
 
@@ -38,17 +78,20 @@ class WRFRun:
38
78
  """
39
79
  ``WRFRun`` is a context class to use all functions in ``wrfrun`` package.
40
80
  """
41
- _instance = None
42
- _initialized = False
43
81
 
44
82
  def __init__(
45
- self, config_file: str, init_workspace=True,
46
- start_server=False, submit_job=False, prepare_wps_data=False,
83
+ self,
84
+ config_file: str,
85
+ init_workspace=True,
86
+ start_server=False,
87
+ submit_job=False,
88
+ prepare_wps_data=False,
47
89
  wps_data_area: Optional[Tuple[int, int, int, int]] = None,
48
- skip_domain_confirm=False
90
+ skip_domain_confirm=False,
49
91
  ):
50
92
  """
51
- WRFRun, a context class to achieve some goals before and after running WRF, like save a copy of config file, start and close WRFRunServer.
93
+ Context class to achieve some goals before and after running WRF,
94
+ like saving a copy of config file, starting and closing WRFRunServer.
52
95
 
53
96
  :param config_file: ``wrfrun`` config file's path.
54
97
  :type config_file: str
@@ -60,15 +103,13 @@ class WRFRun:
60
103
  :type submit_job: bool
61
104
  :param prepare_wps_data: If True, download input datas for WPS first.
62
105
  :type prepare_wps_data: bool
63
- :param wps_data_area: If ``prepare_wps_data==True``, you need to give the area range of input data so download function can download data from ERA5.
106
+ :param wps_data_area: If ``prepare_wps_data==True``, you need to give the area range of input data,
107
+ so download function can download data from ERA5.
64
108
  :type wps_data_area: tuple
65
109
  :param skip_domain_confirm: If ``True``, skip domain confirm.
66
110
  :type skip_domain_confirm: bool
67
111
  :return:
68
112
  """
69
- if self._initialized:
70
- return
71
-
72
113
  # variables for running WRFRunServer
73
114
  self._start_server = start_server
74
115
  self._wrfrun_server: Union[WRFRunServer, None] = None
@@ -85,30 +126,22 @@ class WRFRun:
85
126
  self._entry_file_dir_path = dirname(self._entry_file_path)
86
127
  self._replay_configs = None
87
128
 
88
- # make sure we can read the config file, because sometimes the user may run the Python script in a different path.
129
+ # make sure we can read the config file,
130
+ # because sometimes the user may run the Python script in a different path.
89
131
  abs_config_path = f"{self._entry_file_dir_path}/{config_file}"
90
- init_wrfrun_config(abs_config_path)
91
-
92
- self._record_output_path = None
93
- self._record_include_data = False
94
- self._WRFRUNReplay = ExecConfigRecorder
95
-
96
- self._initialized = True
132
+ WRFRUN.init_wrfrun_config(abs_config_path)
97
133
 
98
- def __new__(cls, *args, **kwargs):
99
- if cls._instance is None:
100
- cls._instance = super().__new__(cls)
101
-
102
- return cls._instance
134
+ self._WRFRUNReplay: Optional[ExecutableRecorder] = None
103
135
 
104
136
  def __enter__(self):
105
137
  # check workspace
106
138
  if not check_workspace():
107
- logger.info(f"Force re-create workspace because it is broken.")
139
+ logger.info("Force re-create workspace because it is broken.")
108
140
  self._init_workspace = True
109
141
 
110
142
  # here is the condition we need to initialize workspace:
111
- # 1. submit_job = True and init_workspace = True, do prepare_workspace before submitting the task to job scheduler.
143
+ # 1. submit_job = True and init_workspace = True,
144
+ # do prepare_workspace before submitting the task to job scheduler.
112
145
  # 2. submit_job = False and init_workspace = True, do prepare_workspace.
113
146
  if self._submit_job and not in_job_scheduler():
114
147
  if self._init_workspace:
@@ -121,7 +154,7 @@ class WRFRun:
121
154
  prepare_scheduler_script(self._entry_file_path)
122
155
 
123
156
  call_subprocess(["qsub", f"{self._entry_file_dir_path}/run.sh"])
124
- logger.info(f"Work has been submit to PBS system")
157
+ logger.info("Work has been submit to PBS system")
125
158
  exit(0)
126
159
 
127
160
  elif not self._submit_job:
@@ -132,7 +165,7 @@ class WRFRun:
132
165
  confirm_model_area()
133
166
 
134
167
  # save a copy of config to the output path
135
- WRFRUNConfig.save_wrfrun_config(f"{WRFRUNConfig.WRFRUN_OUTPUT_PATH}/config.toml")
168
+ WRFRUN.config.save_wrfrun_config(f"{WRFRUN.config.WRFRUN_OUTPUT_PATH}/config.toml")
136
169
 
137
170
  # check if we need to start a server
138
171
  if self._start_server:
@@ -140,14 +173,14 @@ class WRFRun:
140
173
  self._start_wrfrun_server()
141
174
 
142
175
  # change status
143
- WRFRUNConfig.set_wrfrun_context(True)
176
+ WRFRUN.config.set_wrfrun_context(True)
144
177
 
145
- logger_add_file_handler(WRFRUNConfig.get_log_path())
178
+ logger_add_file_handler(WRFRUN.config.get_log_path())
146
179
 
147
180
  if self._prepare_wps_data:
148
181
  if self._wps_data_area is None:
149
- logger.error(f"If you want wrfrun preparing data, you need to give `wps_data_area`")
150
- raise ValueError(f"If you want wrfrun preparing data, you need to give `wps_data_area`")
182
+ logger.error("If you want wrfrun preparing data, you need to give `wps_data_area`")
183
+ raise ValueError("If you want wrfrun preparing data, you need to give `wps_data_area`")
151
184
  else:
152
185
  prepare_wps_input_data(self._wps_data_area)
153
186
 
@@ -158,14 +191,14 @@ class WRFRun:
158
191
  def __exit__(self, exc_type, exc_val, exc_tb):
159
192
  # stop thread if needed
160
193
  if self._start_server:
161
- stop_server(self._ip, self._port) # type: ignore
194
+ stop_server(self._ip, self._port) # type: ignore
162
195
 
163
- if exc_type is None and WRFRUNConfig.IS_RECORDING:
196
+ if exc_type is None and self._WRFRUNReplay is not None:
164
197
  self._WRFRUNReplay.export_replay_file()
165
198
  self._WRFRUNReplay.clear_records()
166
199
 
167
200
  # change status
168
- WRFRUNConfig.set_wrfrun_context(False)
201
+ WRFRUN.config.set_wrfrun_context(False)
169
202
 
170
203
  clear_model_logs()
171
204
 
@@ -173,14 +206,14 @@ class WRFRun:
173
206
 
174
207
  def _start_wrfrun_server(self):
175
208
  """
176
- Start a WRFRunServer.
209
+ Start a WRFRunServer to report simulation progress.
177
210
  """
178
211
  # read ip and port settings from config
179
- socket_ip, socket_port = WRFRUNConfig.get_socket_server_config()
212
+ socket_ip, socket_port = WRFRUN.config.get_socket_server_config()
180
213
 
181
214
  # get simulate settings
182
- start_date = WRFRUNConfig.get_model_config("wrf")["time"]["start_date"]
183
- end_date = WRFRUNConfig.get_model_config("wrf")["time"]["end_date"]
215
+ start_date = WRFRUN.config.get_model_config("wrf")["time"]["start_date"]
216
+ end_date = WRFRUN.config.get_model_config("wrf")["time"]["end_date"]
184
217
 
185
218
  start_date = start_date[0] if isinstance(start_date, list) else start_date
186
219
  end_date = end_date[0] if isinstance(end_date, list) else end_date
@@ -190,55 +223,46 @@ class WRFRun:
190
223
  simulate_seconds = time_delta.days * 24 * 60 * 60 + time_delta.seconds
191
224
 
192
225
  # init server
193
- self._wrfrun_server = WRFRunServer(
194
- start_date, simulate_seconds, (socket_ip, socket_port),
195
- WRFRunServerHandler
196
- )
226
+ self._wrfrun_server = WRFRunServer(start_date, simulate_seconds, (socket_ip, socket_port), WRFRunServerHandler)
197
227
 
198
228
  # get ip and port from instance, because the port may change
199
- self._ip, self._port = self._wrfrun_server.server_address
229
+ self._ip, self._port = self._wrfrun_server.server_address # type: ignore
200
230
 
201
231
  logger.info(f"Start socket server on {self._ip}:{self._port}")
202
232
 
203
233
  # start server thread
204
- self._wrfrun_server_thread = threading.Thread(
205
- target=self._wrfrun_server.serve_forever
206
- )
234
+ self._wrfrun_server_thread = threading.Thread(target=self._wrfrun_server.serve_forever)
207
235
  self._wrfrun_server_thread.daemon = True
208
236
  self._wrfrun_server_thread.start()
209
237
 
210
238
  def record_simulation(self, output_path: str, include_data=False):
211
239
  """
212
- Change settings, so wrfrun can record simulation and generate a replay file.
240
+ Start to record simulation. Simulation parts before this function call will not be recorded.
213
241
 
214
242
  :param output_path: Output file path.
215
243
  :type output_path: str
216
244
  :param include_data: If includes data.
217
245
  :type include_data: bool
218
- :return:
219
- :rtype:
220
246
  """
221
- self._record_output_path = output_path
222
- self._record_include_data = include_data
223
- self._WRFRUNReplay = self._WRFRUNReplay.reinit(save_path=output_path, include_data=include_data)
247
+ WRFRUN.init_recorder(output_path, include_data)
248
+ WRFRUN.config.IS_RECORDING = True
249
+ self._WRFRUNReplay = WRFRUN.record
224
250
 
225
251
  def replay_simulation(self, replay_file: str):
226
252
  """
227
- Replay the simulation without any changes.
253
+ Replay the whole simulation with settings from the ``replay_file``.
228
254
 
229
- :param replay_file:
230
- :type replay_file:
231
- :return:
232
- :rtype:
255
+ :param replay_file: ``.replay`` file path.
256
+ :type replay_file: str
233
257
  """
234
- WRFRUNConfig.check_wrfrun_context(True)
258
+ WRFRUN.config.check_wrfrun_context(True)
235
259
 
236
260
  if self._replay_configs is not None:
237
261
  del self._replay_configs
238
262
 
239
263
  self._replay_configs = replay_config_generator(replay_file)
240
264
 
241
- WRFRUNConfig.IS_IN_REPLAY = True
265
+ WRFRUN.config.IS_IN_REPLAY = True
242
266
 
243
267
  try:
244
268
  for _, executable in self._replay_configs:
@@ -247,30 +271,34 @@ class WRFRun:
247
271
  except WRFRunBasicError:
248
272
  logger.error("Failed to replay the simulation")
249
273
 
250
- WRFRUNConfig.IS_IN_REPLAY = False
274
+ WRFRUN.config.IS_IN_REPLAY = False
251
275
 
252
- def replay_executables(self, replay_file: str):
276
+ def replay_executables(self, replay_file: str) -> Generator[tuple[str, ExecutableBase], None, None]:
253
277
  """
254
- Replay the simulation without any changes.
278
+ Read settings from the ``replay_file``, and yield ``Executable`` name and instance in order.
255
279
 
256
- :param replay_file:
257
- :type replay_file:
258
- :return:
259
- :rtype:
280
+ >>> with WRFRun("config.toml") as wrf_run:
281
+ >>> for name, _exec in wrf_run.replay_executables("example.replay"):
282
+ >>> _exec()
283
+
284
+ :param replay_file: ``.replay`` file path.
285
+ :type replay_file: str
286
+ :return: Generator that yields ``Executable`` name and instance.
287
+ :rtype: Generator[tuple[str, ExecutableBase]]
260
288
  """
261
- WRFRUNConfig.check_wrfrun_context(True)
289
+ WRFRUN.config.check_wrfrun_context(True)
262
290
 
263
291
  if self._replay_configs is not None:
264
292
  del self._replay_configs
265
293
 
266
294
  self._replay_configs = replay_config_generator(replay_file)
267
295
 
268
- WRFRUNConfig.IS_IN_REPLAY = True
296
+ WRFRUN.config.IS_IN_REPLAY = True
269
297
 
270
298
  for name, executable in self._replay_configs:
271
299
  yield name, executable
272
300
 
273
- WRFRUNConfig.IS_IN_REPLAY = False
301
+ WRFRUN.config.IS_IN_REPLAY = False
274
302
 
275
303
 
276
304
  __all__ = ["WRFRun"]
@@ -23,6 +23,7 @@ Submodules
23
23
  env <scheduler.env>
24
24
  lsf <scheduler.lsf>
25
25
  pbs <scheduler.pbs>
26
+ script <scheduler.script>
26
27
  slurm <scheduler.slurm>
27
28
  utils <scheduler.utils>
28
29
  """
wrfrun/scheduler/lsf.py CHANGED
@@ -10,8 +10,9 @@ Scheduler interface for LSF system.
10
10
  lsf_generate_settings
11
11
  """
12
12
 
13
- from wrfrun.core import get_wrfrun_config
13
+ from wrfrun.core import WRFRUN
14
14
  from wrfrun.res import SCHEDULER_LSF_TEMPLATE
15
+
15
16
  from .utils import get_core_num
16
17
 
17
18
 
@@ -22,7 +23,7 @@ def lsf_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
25
- WRFRUNConfig = get_wrfrun_config()
26
+ WRFRUNConfig = WRFRUN.config
26
27
 
27
28
  # get log path and job scheduler config
28
29
  log_path = WRFRUNConfig.get_log_path()
wrfrun/scheduler/pbs.py CHANGED
@@ -10,8 +10,9 @@ Scheduler interface for PBS system.
10
10
  pbs_generate_settings
11
11
  """
12
12
 
13
- from wrfrun.core import get_wrfrun_config
13
+ from wrfrun.core import WRFRUN
14
14
  from wrfrun.res import SCHEDULER_PBS_TEMPLATE
15
+
15
16
  from .utils import get_core_num
16
17
 
17
18
 
@@ -22,7 +23,7 @@ def pbs_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
25
- WRFRUNConfig = get_wrfrun_config()
26
+ WRFRUNConfig = WRFRUN.config
26
27
 
27
28
  # get log path and job scheduler config
28
29
  log_path = WRFRUNConfig.get_log_path()
@@ -1,8 +1,21 @@
1
+ """
2
+ wrfrun.scheduler.script
3
+ #######################
4
+
5
+ Function to prepare bash script to commit job to scheduler.
6
+
7
+ .. autosummary::
8
+ :toctree: generated/
9
+
10
+ prepare_scheduler_script
11
+ """
12
+
1
13
  from os.path import abspath, dirname, exists
2
14
 
3
- from wrfrun import get_wrfrun_config
15
+ from wrfrun.core import WRFRUN
16
+ from wrfrun.log import logger
4
17
  from wrfrun.res import RUN_SH_TEMPLATE
5
- from wrfrun.utils import logger
18
+
6
19
  from .lsf import lsf_generate_settings
7
20
  from .pbs import pbs_generate_settings
8
21
  from .slurm import slurm_generate_settings
@@ -15,7 +28,7 @@ def prepare_scheduler_script(main_file_path: str):
15
28
  :param main_file_path: Path of the main entry file.
16
29
  :type main_file_path: str
17
30
  """
18
- WRFRUNConfig = get_wrfrun_config()
31
+ WRFRUNConfig = WRFRUN.config
19
32
 
20
33
  # check main file path
21
34
  if not exists(main_file_path):
@@ -43,7 +56,7 @@ def prepare_scheduler_script(main_file_path: str):
43
56
  raise ValueError(f"Unknown scheduler name: {scheduler_configs['job_scheduler']}")
44
57
 
45
58
  # generate environment settings
46
- env_settings = 'export WRFRUN_ENV_JOB_SCHEDULER=1\n'
59
+ env_settings = "export WRFRUN_ENV_JOB_SCHEDULER=1\n"
47
60
  if len(scheduler_configs["env_settings"]) > 0:
48
61
  for key in scheduler_configs["env_settings"]:
49
62
  env_settings += f"export {key}={scheduler_configs['env_settings'][key]}\n"
@@ -54,7 +67,6 @@ def prepare_scheduler_script(main_file_path: str):
54
67
  # generate shell script
55
68
  shell_template_path = WRFRUNConfig.parse_resource_uri(RUN_SH_TEMPLATE)
56
69
  with open(f"{dir_path}/run.sh", "w") as f:
57
-
58
70
  with open(shell_template_path, "r") as f_template:
59
71
  template = f_template.read()
60
72
 
wrfrun/scheduler/slurm.py CHANGED
@@ -10,8 +10,9 @@ Scheduler interface for Slurm system.
10
10
  slurm_generate_settings
11
11
  """
12
12
 
13
- from wrfrun.core import get_wrfrun_config
13
+ from wrfrun.core import WRFRUN
14
14
  from wrfrun.res import SCHEDULER_SLURM_TEMPLATE
15
+
15
16
  from .utils import get_core_num
16
17
 
17
18
 
@@ -22,7 +23,7 @@ def slurm_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
25
- WRFRUNConfig = get_wrfrun_config()
26
+ WRFRUNConfig = WRFRUN.config
26
27
 
27
28
  # get log path and job scheduler config
28
29
  log_path = WRFRUNConfig.get_log_path()
wrfrun/scheduler/utils.py CHANGED
@@ -1,4 +1,16 @@
1
- from wrfrun.core import get_wrfrun_config
1
+ """
2
+ wrfrun.scheduler.utils
3
+ ######################
4
+
5
+ Utility functions used by ``wrfrun`` scheduler part.
6
+
7
+ .. autosummary::
8
+ :toctree: generated/
9
+
10
+ get_core_num
11
+ """
12
+
13
+ from wrfrun.core import WRFRUN
2
14
 
3
15
 
4
16
  def get_core_num() -> int:
@@ -8,7 +20,7 @@ def get_core_num() -> int:
8
20
  :return: Core number.
9
21
  :rtype: int
10
22
  """
11
- return get_wrfrun_config()["core_num"]
23
+ return WRFRUN.config["core_num"]
12
24
 
13
25
 
14
26
  __all__ = ["get_core_num"]