wrfrun 0.1.7__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 (46) hide show
  1. wrfrun/__init__.py +3 -0
  2. wrfrun/core/__init__.py +5 -0
  3. wrfrun/core/base.py +680 -0
  4. wrfrun/core/config.py +717 -0
  5. wrfrun/core/error.py +80 -0
  6. wrfrun/core/replay.py +113 -0
  7. wrfrun/core/server.py +212 -0
  8. wrfrun/data.py +418 -0
  9. wrfrun/extension/__init__.py +1 -0
  10. wrfrun/extension/littler/__init__.py +1 -0
  11. wrfrun/extension/littler/utils.py +599 -0
  12. wrfrun/extension/utils.py +66 -0
  13. wrfrun/model/__init__.py +7 -0
  14. wrfrun/model/base.py +14 -0
  15. wrfrun/model/plot.py +54 -0
  16. wrfrun/model/utils.py +34 -0
  17. wrfrun/model/wrf/__init__.py +6 -0
  18. wrfrun/model/wrf/_metgrid.py +71 -0
  19. wrfrun/model/wrf/_ndown.py +39 -0
  20. wrfrun/model/wrf/core.py +805 -0
  21. wrfrun/model/wrf/exec_wrap.py +101 -0
  22. wrfrun/model/wrf/geodata.py +301 -0
  23. wrfrun/model/wrf/namelist.py +377 -0
  24. wrfrun/model/wrf/scheme.py +311 -0
  25. wrfrun/model/wrf/vtable.py +65 -0
  26. wrfrun/pbs.py +86 -0
  27. wrfrun/plot/__init__.py +1 -0
  28. wrfrun/plot/wps.py +188 -0
  29. wrfrun/res/__init__.py +22 -0
  30. wrfrun/res/config.toml.template +136 -0
  31. wrfrun/res/extension/plotgrids.ncl +216 -0
  32. wrfrun/res/job_scheduler/pbs.template +6 -0
  33. wrfrun/res/job_scheduler/slurm.template +6 -0
  34. wrfrun/res/namelist/namelist.input.da_wrfvar.template +261 -0
  35. wrfrun/res/namelist/namelist.input.dfi.template +260 -0
  36. wrfrun/res/namelist/namelist.input.real.template +256 -0
  37. wrfrun/res/namelist/namelist.input.wrf.template +256 -0
  38. wrfrun/res/namelist/namelist.wps.template +44 -0
  39. wrfrun/res/namelist/parame.in.template +11 -0
  40. wrfrun/res/run.sh.template +16 -0
  41. wrfrun/run.py +264 -0
  42. wrfrun/utils.py +257 -0
  43. wrfrun/workspace.py +88 -0
  44. wrfrun-0.1.7.dist-info/METADATA +67 -0
  45. wrfrun-0.1.7.dist-info/RECORD +46 -0
  46. wrfrun-0.1.7.dist-info/WHEEL +4 -0
wrfrun/utils.py ADDED
@@ -0,0 +1,257 @@
1
+ import logging
2
+ import subprocess
3
+ from datetime import datetime
4
+ from os import chdir, getcwd, makedirs
5
+ from os.path import exists
6
+ from shutil import rmtree
7
+ from time import time
8
+ from typing import Optional, List, Dict
9
+
10
+ from rich.logging import RichHandler
11
+
12
+
13
+ def set_logger(logger_list: List[str], logger_level: Optional[Dict] = None):
14
+ """
15
+ This function will replace all handlers of each logger in ``logger_list`` with RichHandler.
16
+ If there are some custom handlers in logger, they will be replaced too.
17
+
18
+ :param logger_list: A list contains loggers.
19
+ :type logger_list: list
20
+ :param logger_level: You can specify the log level in ``logger_level``, with the name of logger is the key, and the level of logger is the value.
21
+ Default if None, with which all loggers' level will be set to ``logging.WARNING``.
22
+ :type logger_level: list | None
23
+ :return:
24
+ :rtype:
25
+ """
26
+ formatter = logging.Formatter(
27
+ "%(name)s :: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"
28
+ )
29
+ # use rich handler
30
+ handler = RichHandler()
31
+ handler.setFormatter(formatter)
32
+
33
+ for logger_name in logger_list:
34
+ if logger_name in logging.root.manager.loggerDict:
35
+ _logger = logging.getLogger(logger_name)
36
+ for _handler in _logger.handlers:
37
+ _logger.removeHandler(_handler)
38
+ _logger.addHandler(handler)
39
+
40
+ if logger_level is not None and logger_name in logger_level:
41
+ _logger.setLevel(logger_level[logger_name])
42
+ else:
43
+ _logger.setLevel(logging.WARNING)
44
+
45
+
46
+ # init wrfrun logger
47
+ logger = logging.getLogger("wrfrun")
48
+ set_logger(["wrfrun", ], {"wrfrun": logging.DEBUG})
49
+
50
+
51
+ def unify_logger_format():
52
+ """
53
+ This function is only supposed to be used internally.
54
+ This function will replace all handlers of each logger with ``rich.logging.RichHandler``.
55
+ Use this carefully.
56
+
57
+ :return:
58
+ :rtype:
59
+ """
60
+ set_logger(
61
+ ["cdsapi", "cfgrib", "datapi"],
62
+ {
63
+ "cdsapi": logging.INFO,
64
+ "cfgrib": logging.ERROR,
65
+ "datapi": logging.INFO
66
+ }
67
+ )
68
+
69
+
70
+ def check_path(*args, force=False):
71
+ """Check and create all the path in *args
72
+
73
+ Returns:
74
+
75
+ """
76
+ for _path in args:
77
+ if exists(_path) and force:
78
+ rmtree(_path)
79
+ if not exists(_path):
80
+ makedirs(_path)
81
+
82
+
83
+ def logger_add_file_handler(log_path: str):
84
+ """Add file handler to logger
85
+
86
+ Args:
87
+ log_path (str): Folder to place log file
88
+ """
89
+ # check log save path
90
+ check_path(log_path)
91
+
92
+ # add file handler
93
+ file_handler = logging.FileHandler(
94
+ f"{log_path}/{datetime.fromtimestamp(time()).strftime('%Y-%m-%d %H:%M:%S')}.log")
95
+ file_handler.setFormatter(logging.Formatter(
96
+ "%(asctime)s - %(name)s - %(levelname)s :: %(message)s", datefmt="%m-%d %H:%M:%S"))
97
+ logger.addHandler(file_handler)
98
+
99
+
100
+ def rectify_domain_size(point_num: int, nest_ratio: int) -> int:
101
+ """Rectify domain size.
102
+
103
+ Args:
104
+ point_num (int): Point number of one side.
105
+ nest_ratio (int): The nesting ratio relative to the domain’s parent.
106
+
107
+ Returns:
108
+ int: New size.
109
+ """
110
+ # calculate remainder
111
+ point_num_mod = (point_num - 1) % nest_ratio
112
+
113
+ if point_num_mod == 0:
114
+ return point_num
115
+
116
+ if point_num_mod < nest_ratio / 2:
117
+ # # point_num_mod is closer to (nest_ratio - 1) than nest_ratio
118
+ point_num -= point_num_mod
119
+ else:
120
+ # # point_num_mod is closer to nest_ratio than (nest_ratio - 1)
121
+ point_num += (nest_ratio - point_num_mod)
122
+
123
+ return point_num
124
+
125
+
126
+ def _calculate_domain_shape(step: float, resolution: int, grid_resolution=110, nest_ratio=1) -> int:
127
+ """Calculate domain shape based on its area
128
+
129
+ Args:
130
+ step (float): Length of the side. Unit: degree.
131
+ resolution (int): Resolution of domain. Unit: km.
132
+ grid_resolution (int, optional): Resolution of grid. Unit: km. Defaults to 110.
133
+ nest_ratio (int, optional): The nesting ratio relative to the domain’s parent.
134
+
135
+ Returns:
136
+ tuple[int, int]: (length of x, length of y)
137
+ """
138
+ # calculate res based on doamin area and resolution
139
+ res = int(step * grid_resolution) // resolution
140
+
141
+ # rectify
142
+
143
+ return rectify_domain_size(res, nest_ratio=nest_ratio)
144
+
145
+
146
+ def calculate_domain_shape(lon_step: float, lat_step: float, resolution: int, grid_resolution=110, nest_ratio=1) -> tuple[int, int]:
147
+ """Calculate domain shape based on its area
148
+
149
+ Args:
150
+ lon_step (float): Length in X direction. Unit: degree.
151
+ lat_step (float): Length in Y direction. Unit: degree.
152
+ resolution (int): Resolution of domain. Unit: km.
153
+ grid_resolution (int, optional): Resolution of grid. Unit: km. Defaults to 110.
154
+ nest_ratio (int, optional): The nesting ratio relative to the domain’s parent.
155
+
156
+ Returns:
157
+ tuple[int, int]: (length of x, length of y)
158
+ """
159
+
160
+ return (
161
+ _calculate_domain_shape(
162
+ lon_step, resolution, grid_resolution=grid_resolution, nest_ratio=nest_ratio),
163
+ _calculate_domain_shape(
164
+ lat_step, resolution, grid_resolution=grid_resolution, nest_ratio=nest_ratio)
165
+ )
166
+
167
+
168
+ def _check_domain_shape(point_num: int, nest_ratio: int) -> bool:
169
+ """Check domain shape.
170
+
171
+ Args:
172
+ point_num (int): Point number of one side.
173
+ nest_ratio (int): The nesting ratio relative to the domain’s parent.
174
+
175
+ Returns:
176
+ bool: True if pass check else False.
177
+ """
178
+ if (point_num - 1) % nest_ratio != 0:
179
+ return False
180
+ else:
181
+ return True
182
+
183
+
184
+ def check_domain_shape(x_point_num: int, y_point_num: int, nest_ratio: int) -> tuple[bool, bool]:
185
+ """Check domain shape.
186
+
187
+ Args:
188
+ x_point_num (int): Point number of X side.
189
+ y_point_num (int): Point number of Y side.
190
+ nest_ratio (int): The nesting ratio relative to the domain’s parent.
191
+
192
+ Returns:
193
+ tuple[bool, bool]: Tuple of bool. True if pass check else False
194
+ """
195
+ return (
196
+ _check_domain_shape(x_point_num, nest_ratio=nest_ratio),
197
+ _check_domain_shape(y_point_num, nest_ratio=nest_ratio)
198
+ )
199
+
200
+
201
+ def check_subprocess_status(status: subprocess.CompletedProcess):
202
+ """Check subprocess return code and print log if their return code != 0
203
+
204
+ Args:
205
+ status (CompletedProcess): Status from subprocess.
206
+ """
207
+ if status.returncode != 0:
208
+ # print command
209
+ command = status.args
210
+ logger.error(f"Failed to exec command: {command}")
211
+
212
+ # print log
213
+ logger.error(f"====== stdout ======")
214
+ logger.error(status.stdout.decode())
215
+ logger.error(f"====== ====== ======")
216
+ logger.error(f"====== stderr ======")
217
+ logger.error(status.stderr.decode())
218
+ logger.error(f"====== ====== ======")
219
+
220
+ # raise error
221
+ raise RuntimeError
222
+
223
+
224
+ def call_subprocess(command: list[str], work_path: Optional[str] = None, print_output=False):
225
+ """
226
+ Execute the given command in system shell.
227
+
228
+ :param command: A list contains the command and parameters to be executed.
229
+ :type command: list
230
+ :param work_path: The work path of the command.
231
+ If None, works in current directory.
232
+ :type work_path: str | None
233
+ :param print_output: If print standard output and error in the logger.
234
+ :type print_output: bool
235
+ :return:
236
+ :rtype:
237
+ """
238
+ if work_path is not None:
239
+ origin_path = getcwd()
240
+ chdir(work_path)
241
+ else:
242
+ origin_path = None
243
+
244
+ status = subprocess.run(' '.join(command), shell=True, capture_output=True)
245
+
246
+ if origin_path is not None:
247
+ chdir(origin_path)
248
+
249
+ check_subprocess_status(status)
250
+
251
+ if print_output:
252
+ logger.info(status.stdout.decode())
253
+ logger.warning(status.stderr.decode())
254
+
255
+
256
+ __all__ = ["logger", "check_path", "logger_add_file_handler", "calculate_domain_shape", "rectify_domain_size", "check_domain_shape",
257
+ "check_subprocess_status", "call_subprocess", "set_logger", "unify_logger_format"]
wrfrun/workspace.py ADDED
@@ -0,0 +1,88 @@
1
+ """
2
+ This file contains functions to interact with WRF workspace
3
+ """
4
+
5
+ from os import listdir, makedirs, symlink
6
+ from os.path import exists
7
+
8
+ from .core import WRFRUNConfig
9
+ from .utils import check_path, logger
10
+
11
+
12
+ def prepare_workspace():
13
+ """Initialize workspace
14
+
15
+ """
16
+ logger.info(f"Initialize workspace...")
17
+
18
+ # extract WRF path
19
+ wrf_config = WRFRUNConfig.get_model_config("wrf")
20
+ wps_path = wrf_config["wps_path"]
21
+ wrf_path = wrf_config["wrf_path"]
22
+ wrfda_path = wrf_config["wrfda_path"]
23
+
24
+ WRFRUN_TEMP_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRFRUN_TEMP_PATH)
25
+ WORK_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRFRUN_WORKSPACE_PATH)
26
+ REPLAY_WORK_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRFRUN_REPLAY_WORK_PATH)
27
+ WPS_WORK_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WPS_WORK_PATH)
28
+ WRF_WORK_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRF_WORK_PATH)
29
+ WRFDA_WORK_PATH = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRFDA_WORK_PATH)
30
+ output_path = WRFRUNConfig.parse_resource_uri(WRFRUNConfig.WRFRUN_OUTPUT_PATH)
31
+
32
+ # check folder
33
+ check_path(WRFRUN_TEMP_PATH)
34
+ check_path(REPLAY_WORK_PATH, force=True)
35
+ check_path(output_path)
36
+
37
+ if exists(wrfda_path):
38
+ WRFRUNConfig.USE_WRFDA = True
39
+
40
+ # create folder to run WPS, and WRF
41
+ # check the path
42
+ if not (exists(wps_path) and exists(wrf_path)):
43
+ logger.error(f"Your WPS or WRF path is wrong")
44
+ raise FileNotFoundError(f"Your WPS or WRF path is wrong")
45
+
46
+ # remove old file
47
+ if exists(WORK_PATH):
48
+ logger.info(f"Remove old files...")
49
+ check_path(WPS_WORK_PATH, f"{WPS_WORK_PATH}/outputs",
50
+ WRF_WORK_PATH, WRFDA_WORK_PATH, force=True)
51
+ logger.info(f"Link essential files...")
52
+
53
+ # link {wps_path}/*
54
+ # collect file except folder geogrid
55
+ file_list = [
56
+ x for x in listdir(wps_path) if x not in ["geogrid", "namelist.wps"]
57
+ ]
58
+ for file in file_list:
59
+ symlink(f"{wps_path}/{file}", f"{WPS_WORK_PATH}/{file}")
60
+
61
+ # create folder geogrid and link default GEOGRID file
62
+ makedirs(f"{WPS_WORK_PATH}/geogrid")
63
+ symlink(
64
+ f"{wps_path}/geogrid/GEOGRID.TBL", f"{WPS_WORK_PATH}/geogrid/GEOGRID.TBL"
65
+ )
66
+
67
+ # # link {wrf_path}/run/*, except namelist.input
68
+ file_list = [x for x in listdir(
69
+ f"{wrf_path}/run") if not x.startswith("namelist")]
70
+ for file in file_list:
71
+ symlink(f"{wrf_path}/run/{file}", f"{WRF_WORK_PATH}/{file}")
72
+
73
+ if WRFRUNConfig.USE_WRFDA:
74
+ # # link {wrfda_path}/bin/*.exe
75
+ file_list = ["da_wrfvar.exe", "da_update_bc.exe"]
76
+ for file in file_list:
77
+ symlink(f"{wrfda_path}/var/build/{file}", f"{WRFDA_WORK_PATH}/{file}")
78
+
79
+ # # link {wrfda_path}/var/run/*
80
+ file_list = listdir(f"{wrfda_path}/var/run")
81
+ for file in file_list:
82
+ symlink(f"{wrfda_path}/var/run/{file}", f"{WRFDA_WORK_PATH}/{file}")
83
+
84
+ # # link {wrfda_path}/run/LANDUSE.TBL
85
+ symlink(f"{wrfda_path}/run/LANDUSE.TBL", f"{WRFDA_WORK_PATH}/LANDUSE.TBL")
86
+
87
+
88
+ __all__ = ["prepare_workspace"]
@@ -0,0 +1,67 @@
1
+ Metadata-Version: 2.1
2
+ Name: wrfrun
3
+ Version: 0.1.7
4
+ Summary: wrfrun is a comprehensive toolkit for managing and using WRF
5
+ Keywords: WRF
6
+ Author-Email: Syize <syizeliu@gmail.com>
7
+ Maintainer-Email: Syize <syizeliu@gmail.com>
8
+ License: GPL-3.0-or-later
9
+ Project-URL: homepage, https://github.com/Syize/wrfrun
10
+ Project-URL: repository, https://github.com/Syize/wrfrun
11
+ Project-URL: documentation, https://wrfrun.syize.cn
12
+ Project-URL: Bug Tracker, https://github.com/Syize/wrfrun/issues
13
+ Requires-Python: <3.13
14
+ Requires-Dist: numpy<2.0.0
15
+ Requires-Dist: xarray
16
+ Requires-Dist: netCDF4
17
+ Requires-Dist: rich
18
+ Requires-Dist: pandas
19
+ Requires-Dist: f90nml
20
+ Requires-Dist: cdsapi
21
+ Requires-Dist: matplotlib
22
+ Requires-Dist: Cartopy
23
+ Requires-Dist: wrf-python
24
+ Requires-Dist: cfgrib
25
+ Requires-Dist: tomli
26
+ Requires-Dist: tomli-w
27
+ Description-Content-Type: text/markdown
28
+
29
+ # wrfrun: A toolkit to control WRF
30
+
31
+ ## What is wrfrun?
32
+
33
+ Using and managing WRF can be a tedious task. WRF's configuration file contains a large number of settings, which generally need to be configured separately for each simulation case, and the user usually needs to rely on other tools or scripts to manage the simulation of different cases, which causes a lot of inconvenience. In addition, the whole process of running the WRF model involves running many programs, which is very time-consuming to run manually and requires the use of scripts to automate certain processes.
34
+
35
+ `wrfrun` is a comprehensive toolkit for managing and using WRF. `wrfrun` wraps the WRF model so that the user only needs to call the corresponding Python function to run the corresponding part of the model. `wrfrun` avoids cluttering up the user's working directory with a lot of useless files by creating a temporary directory in which the WRF model would be run. `wrfrun` automatically saves mode configurations and wrfrun configurations, which makes it easier to manage the simulation and reproduction of different cases. `wrfrun` also provides more features through extensions, which help users to do related research better.
36
+
37
+ ## Main Features
38
+
39
+ The following are the main features that wrfrun wants to achieve. These features have been basically realized, and are still under continuous improvement.
40
+
41
+ - Isolate the WRF runtime directory in a separate temporary directory.
42
+ - Automatic saving of mode output, logs and configurations.
43
+ - Provide an interface to run any part of the WRF model.
44
+ - Real-time parsing of WRF logs, feedback on simulation progress.
45
+ - Support for adding more functionality through extensions.
46
+
47
+ ## Dependencies
48
+
49
+ You need to install `meson` and `ninja` at first, both of which can be installed using `pip`:
50
+
51
+ ```bash
52
+ pip install meson ninja
53
+ ```
54
+
55
+ Make sure the path `$HOME/.local/bin` has been added to your environment variable `PATH`.
56
+
57
+ ## Installation
58
+
59
+ Install using pip:
60
+
61
+ ```bash
62
+ pip install wrfrun
63
+ ```
64
+
65
+ ## Documentation
66
+
67
+ Please check [Wiki](https://wrfrun.syize.cn).
@@ -0,0 +1,46 @@
1
+ wrfrun-0.1.7.dist-info/METADATA,sha256=nrPBmS0UxcjIiCN9wLyL798-r3OKpirBJUPlWrzobw8,2912
2
+ wrfrun-0.1.7.dist-info/WHEEL,sha256=5J4neoE7k6LMgx4Fz1FHgBiO3YevhJGtNQ3muDrdLQM,75
3
+ wrfrun/__init__.py,sha256=l2zGk2qDWa3EXIlwvzqBYZHOU9273TN75Rmvx_7PAYM,58
4
+ wrfrun/data.py,sha256=AjkDSZqkLROnWLw9qDOBUctoQmJ3R1bkfjnPzLMjPfs,14751
5
+ wrfrun/pbs.py,sha256=gzRHbYqpU-c8lynu39TUKNvmPntvrPwfQVxK337yvjw,2454
6
+ wrfrun/run.py,sha256=0mvuI98gLjq1gP1eaLUZiU1LJMCjtL668aKZTwu3n2g,9114
7
+ wrfrun/utils.py,sha256=v3ZRu3Rd8-pZjo7I0PrJtgBN1zIBAt_nVPs0BP_DFwY,8118
8
+ wrfrun/workspace.py,sha256=5tWIIFxwAE4hkdg_wJALGDc3P0bfwb_IRTIyPIjN-tE,3105
9
+ wrfrun/core/__init__.py,sha256=bf9Fp6VS5i9xB10lazYBOkJapF2jnQpyiB6qucVjp0I,107
10
+ wrfrun/core/base.py,sha256=S9Mqr3LOpos0CP0TsFwtCQl0tLIObIhjX7VxjS0LRDY,23172
11
+ wrfrun/core/config.py,sha256=v7zdhAthlMmjv_BWINxkmgNHLvKZdzQhgM5B-Nlsl7M,23795
12
+ wrfrun/core/error.py,sha256=fCWVC4-GTyDH2obzu9-D_bzF8_uzqZoUi7Ffy0B5qoc,1324
13
+ wrfrun/core/replay.py,sha256=oyV9QppZG99GbAksQqoRxeBQ3jjXU-7YqkpxHRyfBvc,3229
14
+ wrfrun/core/server.py,sha256=KK_yj4J-5F_s-rKO5FK7e8WojsnuZMbhWtMceWYbaBY,6524
15
+ wrfrun/extension/__init__.py,sha256=alIDGBnxWH4JvP-UW-7N99seBBi0r1GV1h8f1ERFBec,21
16
+ wrfrun/extension/utils.py,sha256=OBIAlAXakbh1QhrF2BFlYAFV062ZfJjX0mYJkmcU_RI,2751
17
+ wrfrun/extension/littler/__init__.py,sha256=pG-YPVG0gJIJ6s4xcAz9S_CnUxpUcz33wl9eNUSgxGk,20
18
+ wrfrun/extension/littler/utils.py,sha256=TsN3GiAFszPWF7RNM_hYdARRY_OLL8mYm87UyZupUtU,21615
19
+ wrfrun/model/__init__.py,sha256=lQNNnh3evXZytLAjdnhlIEFWerP1L0XAgDAUQhqIRyE,119
20
+ wrfrun/model/base.py,sha256=WnVNu12ICJgThfZR7kK6_XLCQWVYFsHrdyAz8wl_YRc,218
21
+ wrfrun/model/plot.py,sha256=ATG5nl5kV8YfoeNFIPLCUnnIQIrfIFNGPb9d8raM6S0,1582
22
+ wrfrun/model/utils.py,sha256=Pyj9D9NMKw3wQcZcM7pJaLG09Vov447AxFKoVeZZU2s,1155
23
+ wrfrun/model/wrf/__init__.py,sha256=T3S1BD9QDoW4uq871QW4_8-2BvCRWYEecz71EcdbMaI,136
24
+ wrfrun/model/wrf/core.py,sha256=FEzRXUKK5dENxev3wR_GON5n1Zxq4Hj-Bs_BNP7P_ok,32134
25
+ wrfrun/model/wrf/exec_wrap.py,sha256=gIsGZDAjzRzxt24eo8t-laIK4UBiyKf_ysfAZLlE1og,3918
26
+ wrfrun/model/wrf/geodata.py,sha256=X9OUOm0__5NI7sl2z1F9_ur5wZ4P0HkpBNcRZQYKof0,9740
27
+ wrfrun/model/wrf/_metgrid.py,sha256=i2qILM_1LkdnBZqXXL3swVhMRvhFvq4bOcRPGI6kSzg,2248
28
+ wrfrun/model/wrf/namelist.py,sha256=t_JuWYj4oNNVwzTMKo6BNlv2LIq4t3JC7ZgVkaKfNbA,14923
29
+ wrfrun/model/wrf/_ndown.py,sha256=ZcWttGXiT5FzGCAohmbeNU6bi8GUOUleiTK0ivn2BaI,1548
30
+ wrfrun/model/wrf/scheme.py,sha256=F7HxoaNkkPpjkse5t9sGS3CJDvn_yBdHoaCG7WLdbqY,8524
31
+ wrfrun/model/wrf/vtable.py,sha256=0V4fo0Limnx4oJ2NByq_eHPzj8L4mnHNlrKL34Buw1A,2432
32
+ wrfrun/plot/__init__.py,sha256=9Kn0IgkX10sHEqHJwk7mZV-dP14XMNcvXN8znO89FIw,19
33
+ wrfrun/plot/wps.py,sha256=AQ1B6llNUrPU3PR8XKNLSzs_H-v60a0Wep-8Mcto6NM,5319
34
+ wrfrun/res/__init__.py,sha256=YBcVaM2EZZJkDDvyKdk-WZmcFQoTFENZKCwcIQzEf3I,1133
35
+ wrfrun/res/config.toml.template,sha256=aVXCSzhbV3P-MQCZOk2g-y0auRmqgr3jW920W3wks9g,4386
36
+ wrfrun/res/run.sh.template,sha256=ZN7k0a9ONOtZUQ67JiTva-0DNVJG5O7BdOXQ8-LCscs,247
37
+ wrfrun/res/extension/plotgrids.ncl,sha256=B0mvH1H1j_w7EEana9HmU1XJZtG0w9IccQ54zXpbQG0,7546
38
+ wrfrun/res/namelist/namelist.input.da_wrfvar.template,sha256=Cwc-XPu_spJeQte4duWrulPBOLRMEBtn0mIn0pgMmKY,4912
39
+ wrfrun/res/namelist/namelist.input.dfi.template,sha256=E7MVbIvMopkAM7xGUC4vniC1WOUVbIbdLfkTKHqzX_o,6591
40
+ wrfrun/res/namelist/namelist.input.real.template,sha256=DDUiArtBFmzBwVjkZW4NOrBR34eIOk1vV0VsyL0stsk,6214
41
+ wrfrun/res/namelist/namelist.input.wrf.template,sha256=myrKi79sQ8ABBsmQJkcgN0WLbWJdtMVPIjuAC1MTMuM,6213
42
+ wrfrun/res/namelist/namelist.wps.template,sha256=HlA7-SHs4C-cKRb3h6D0Kl1Y-5VSJ1Lw9hLiXWGAN0Q,1017
43
+ wrfrun/res/namelist/parame.in.template,sha256=vR8JSix20FAKGqj6jK8QuEAeWkGvg8_iptdVlzjPX6o,259
44
+ wrfrun/res/job_scheduler/pbs.template,sha256=m7eyvZkzQRpjs43CvSeZ1biHYNyEJJkgXt3IU5ZhCmg,148
45
+ wrfrun/res/job_scheduler/slurm.template,sha256=BrKL8DcHfpFfv0y0z7Qe_cqjwfzMyF-3V6vM72ehr9Y,312
46
+ wrfrun-0.1.7.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: meson
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any