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/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, 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,24 +78,38 @@ 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
- def __init__(self, config_file: str, init_workspace=True, start_server=False, submit_job=False, prepare_wps_data=False, wps_data_area: Optional[Tuple[int, int, int, int]] = None):
82
+ def __init__(
83
+ self,
84
+ config_file: str,
85
+ init_workspace=True,
86
+ start_server=False,
87
+ submit_job=False,
88
+ prepare_wps_data=False,
89
+ wps_data_area: Optional[Tuple[int, int, int, int]] = None,
90
+ skip_domain_confirm=False,
91
+ ):
45
92
  """
46
- 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.
47
95
 
48
96
  :param config_file: ``wrfrun`` config file's path.
97
+ :type config_file: str
49
98
  :param init_workspace: If True, clean old files in workspace and re-create it.
99
+ :type init_workspace: bool
50
100
  :param start_server: Whether to start WRFRunServer, defaults to True.
101
+ :type start_server: bool
51
102
  :param submit_job: If commit this task to the PBS system, defaults to True.
103
+ :type submit_job: bool
52
104
  :param prepare_wps_data: If True, download input datas for WPS first.
53
- :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.
105
+ :type prepare_wps_data: bool
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.
108
+ :type wps_data_area: tuple
109
+ :param skip_domain_confirm: If ``True``, skip domain confirm.
110
+ :type skip_domain_confirm: bool
54
111
  :return:
55
112
  """
56
- if self._initialized:
57
- return
58
-
59
113
  # variables for running WRFRunServer
60
114
  self._start_server = start_server
61
115
  self._wrfrun_server: Union[WRFRunServer, None] = None
@@ -67,56 +121,51 @@ class WRFRun:
67
121
  self._init_workspace = init_workspace
68
122
  self._prepare_wps_data = prepare_wps_data
69
123
  self._wps_data_area = wps_data_area
124
+ self._skip_domain_confirm = skip_domain_confirm
70
125
  self._entry_file_path = abspath(sys.argv[0])
71
126
  self._entry_file_dir_path = dirname(self._entry_file_path)
72
127
  self._replay_configs = None
73
128
 
74
- # 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.
75
131
  abs_config_path = f"{self._entry_file_dir_path}/{config_file}"
76
- WRFRUNConfig.load_wrfrun_config(abs_config_path)
77
-
78
- self._record_output_path = None
79
- self._record_include_data = False
80
- self._WRFRUNReplay = ExecConfigRecorder
81
-
82
- self._initialized = True
132
+ WRFRUN.init_wrfrun_config(abs_config_path)
83
133
 
84
- def __new__(cls, *args, **kwargs):
85
- if cls._instance is None:
86
- cls._instance = super().__new__(cls)
87
-
88
- return cls._instance
134
+ self._WRFRUNReplay: Optional[ExecutableRecorder] = None
89
135
 
90
136
  def __enter__(self):
91
137
  # check workspace
92
138
  if not check_workspace():
93
- logger.info(f"Force re-create workspace because it is broken.")
139
+ logger.info("Force re-create workspace because it is broken.")
94
140
  self._init_workspace = True
95
141
 
96
142
  # here is the condition we need to initialize workspace:
97
- # 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.
98
145
  # 2. submit_job = False and init_workspace = True, do prepare_workspace.
99
146
  if self._submit_job and not in_job_scheduler():
100
147
  if self._init_workspace:
101
148
  prepare_workspace()
102
149
 
103
150
  # ask user before commit the task
104
- confirm_model_area()
151
+ if not self._skip_domain_confirm:
152
+ confirm_model_area()
105
153
 
106
154
  prepare_scheduler_script(self._entry_file_path)
107
155
 
108
156
  call_subprocess(["qsub", f"{self._entry_file_dir_path}/run.sh"])
109
- logger.info(f"Work has been submit to PBS system")
157
+ logger.info("Work has been submit to PBS system")
110
158
  exit(0)
111
159
 
112
160
  elif not self._submit_job:
113
161
  if self._init_workspace:
114
162
  prepare_workspace()
115
163
 
116
- confirm_model_area()
164
+ if not self._skip_domain_confirm:
165
+ confirm_model_area()
117
166
 
118
167
  # save a copy of config to the output path
119
- 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")
120
169
 
121
170
  # check if we need to start a server
122
171
  if self._start_server:
@@ -124,14 +173,14 @@ class WRFRun:
124
173
  self._start_wrfrun_server()
125
174
 
126
175
  # change status
127
- WRFRUNConfig.set_wrfrun_context(True)
176
+ WRFRUN.config.set_wrfrun_context(True)
128
177
 
129
- logger_add_file_handler(WRFRUNConfig.get_log_path())
178
+ logger_add_file_handler(WRFRUN.config.get_log_path())
130
179
 
131
180
  if self._prepare_wps_data:
132
181
  if self._wps_data_area is None:
133
- logger.error(f"If you want wrfrun preparing data, you need to give `wps_data_area`")
134
- 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`")
135
184
  else:
136
185
  prepare_wps_input_data(self._wps_data_area)
137
186
 
@@ -142,14 +191,14 @@ class WRFRun:
142
191
  def __exit__(self, exc_type, exc_val, exc_tb):
143
192
  # stop thread if needed
144
193
  if self._start_server:
145
- stop_server(self._ip, self._port) # type: ignore
194
+ stop_server(self._ip, self._port) # type: ignore
146
195
 
147
- if exc_type is None and WRFRUNConfig.IS_RECORDING:
196
+ if exc_type is None and self._WRFRUNReplay is not None:
148
197
  self._WRFRUNReplay.export_replay_file()
149
198
  self._WRFRUNReplay.clear_records()
150
199
 
151
200
  # change status
152
- WRFRUNConfig.set_wrfrun_context(False)
201
+ WRFRUN.config.set_wrfrun_context(False)
153
202
 
154
203
  clear_model_logs()
155
204
 
@@ -157,14 +206,14 @@ class WRFRun:
157
206
 
158
207
  def _start_wrfrun_server(self):
159
208
  """
160
- Start a WRFRunServer.
209
+ Start a WRFRunServer to report simulation progress.
161
210
  """
162
211
  # read ip and port settings from config
163
- socket_ip, socket_port = WRFRUNConfig.get_socket_server_config()
212
+ socket_ip, socket_port = WRFRUN.config.get_socket_server_config()
164
213
 
165
214
  # get simulate settings
166
- start_date = WRFRUNConfig.get_model_config("wrf")["time"]["start_date"]
167
- 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"]
168
217
 
169
218
  start_date = start_date[0] if isinstance(start_date, list) else start_date
170
219
  end_date = end_date[0] if isinstance(end_date, list) else end_date
@@ -174,55 +223,46 @@ class WRFRun:
174
223
  simulate_seconds = time_delta.days * 24 * 60 * 60 + time_delta.seconds
175
224
 
176
225
  # init server
177
- self._wrfrun_server = WRFRunServer(
178
- start_date, simulate_seconds, (socket_ip, socket_port),
179
- WRFRunServerHandler
180
- )
226
+ self._wrfrun_server = WRFRunServer(start_date, simulate_seconds, (socket_ip, socket_port), WRFRunServerHandler)
181
227
 
182
228
  # get ip and port from instance, because the port may change
183
- self._ip, self._port = self._wrfrun_server.server_address
229
+ self._ip, self._port = self._wrfrun_server.server_address # type: ignore
184
230
 
185
231
  logger.info(f"Start socket server on {self._ip}:{self._port}")
186
232
 
187
233
  # start server thread
188
- self._wrfrun_server_thread = threading.Thread(
189
- target=self._wrfrun_server.serve_forever
190
- )
234
+ self._wrfrun_server_thread = threading.Thread(target=self._wrfrun_server.serve_forever)
191
235
  self._wrfrun_server_thread.daemon = True
192
236
  self._wrfrun_server_thread.start()
193
237
 
194
238
  def record_simulation(self, output_path: str, include_data=False):
195
239
  """
196
- 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.
197
241
 
198
242
  :param output_path: Output file path.
199
243
  :type output_path: str
200
244
  :param include_data: If includes data.
201
245
  :type include_data: bool
202
- :return:
203
- :rtype:
204
246
  """
205
- self._record_output_path = output_path
206
- self._record_include_data = include_data
207
- 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
208
250
 
209
251
  def replay_simulation(self, replay_file: str):
210
252
  """
211
- Replay the simulation without any changes.
253
+ Replay the whole simulation with settings from the ``replay_file``.
212
254
 
213
- :param replay_file:
214
- :type replay_file:
215
- :return:
216
- :rtype:
255
+ :param replay_file: ``.replay`` file path.
256
+ :type replay_file: str
217
257
  """
218
- WRFRUNConfig.check_wrfrun_context(True)
258
+ WRFRUN.config.check_wrfrun_context(True)
219
259
 
220
260
  if self._replay_configs is not None:
221
261
  del self._replay_configs
222
262
 
223
263
  self._replay_configs = replay_config_generator(replay_file)
224
264
 
225
- WRFRUNConfig.IS_IN_REPLAY = True
265
+ WRFRUN.config.IS_IN_REPLAY = True
226
266
 
227
267
  try:
228
268
  for _, executable in self._replay_configs:
@@ -231,30 +271,34 @@ class WRFRun:
231
271
  except WRFRunBasicError:
232
272
  logger.error("Failed to replay the simulation")
233
273
 
234
- WRFRUNConfig.IS_IN_REPLAY = False
274
+ WRFRUN.config.IS_IN_REPLAY = False
235
275
 
236
- def replay_executables(self, replay_file: str):
276
+ def replay_executables(self, replay_file: str) -> Generator[tuple[str, ExecutableBase], None, None]:
237
277
  """
238
- Replay the simulation without any changes.
278
+ Read settings from the ``replay_file``, and yield ``Executable`` name and instance in order.
239
279
 
240
- :param replay_file:
241
- :type replay_file:
242
- :return:
243
- :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]]
244
288
  """
245
- WRFRUNConfig.check_wrfrun_context(True)
289
+ WRFRUN.config.check_wrfrun_context(True)
246
290
 
247
291
  if self._replay_configs is not None:
248
292
  del self._replay_configs
249
293
 
250
294
  self._replay_configs = replay_config_generator(replay_file)
251
295
 
252
- WRFRUNConfig.IS_IN_REPLAY = True
296
+ WRFRUN.config.IS_IN_REPLAY = True
253
297
 
254
298
  for name, executable in self._replay_configs:
255
299
  yield name, executable
256
300
 
257
- WRFRUNConfig.IS_IN_REPLAY = False
301
+ WRFRUN.config.IS_IN_REPLAY = False
258
302
 
259
303
 
260
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 WRFRUNConfig
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,6 +23,8 @@ def lsf_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
26
+ WRFRUNConfig = WRFRUN.config
27
+
25
28
  # get log path and job scheduler config
26
29
  log_path = WRFRUNConfig.get_log_path()
27
30
 
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 WRFRUNConfig
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,6 +23,8 @@ def pbs_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
26
+ WRFRUNConfig = WRFRUN.config
27
+
25
28
  # get log path and job scheduler config
26
29
  log_path = WRFRUNConfig.get_log_path()
27
30
 
@@ -1,8 +1,21 @@
1
- from os.path import exists, abspath, dirname
1
+ """
2
+ wrfrun.scheduler.script
3
+ #######################
2
4
 
3
- from wrfrun import WRFRUNConfig
5
+ Function to prepare bash script to commit job to scheduler.
6
+
7
+ .. autosummary::
8
+ :toctree: generated/
9
+
10
+ prepare_scheduler_script
11
+ """
12
+
13
+ from os.path import abspath, dirname, exists
14
+
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,6 +28,8 @@ 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
  """
31
+ WRFRUNConfig = WRFRUN.config
32
+
18
33
  # check main file path
19
34
  if not exists(main_file_path):
20
35
  logger.error(f"Wrong path of main entry file: {main_file_path}")
@@ -41,7 +56,7 @@ def prepare_scheduler_script(main_file_path: str):
41
56
  raise ValueError(f"Unknown scheduler name: {scheduler_configs['job_scheduler']}")
42
57
 
43
58
  # generate environment settings
44
- env_settings = 'export WRFRUN_ENV_JOB_SCHEDULER=1\n'
59
+ env_settings = "export WRFRUN_ENV_JOB_SCHEDULER=1\n"
45
60
  if len(scheduler_configs["env_settings"]) > 0:
46
61
  for key in scheduler_configs["env_settings"]:
47
62
  env_settings += f"export {key}={scheduler_configs['env_settings'][key]}\n"
@@ -52,7 +67,6 @@ def prepare_scheduler_script(main_file_path: str):
52
67
  # generate shell script
53
68
  shell_template_path = WRFRUNConfig.parse_resource_uri(RUN_SH_TEMPLATE)
54
69
  with open(f"{dir_path}/run.sh", "w") as f:
55
-
56
70
  with open(shell_template_path, "r") as f_template:
57
71
  template = f_template.read()
58
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 WRFRUNConfig
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,6 +23,8 @@ def slurm_generate_settings(scheduler_config: dict) -> str:
22
23
  :return: Generated settings.
23
24
  :rtype: str
24
25
  """
26
+ WRFRUNConfig = WRFRUN.config
27
+
25
28
  # get log path and job scheduler config
26
29
  log_path = WRFRUNConfig.get_log_path()
27
30
 
wrfrun/scheduler/utils.py CHANGED
@@ -1,4 +1,16 @@
1
- from wrfrun import WRFRUNConfig
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 WRFRUNConfig["core_num"]
23
+ return WRFRUN.config["core_num"]
12
24
 
13
25
 
14
26
  __all__ = ["get_core_num"]