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.
- wrfrun/__init__.py +8 -3
- wrfrun/cli.py +74 -31
- wrfrun/core/__init__.py +27 -10
- wrfrun/core/_config.py +308 -0
- wrfrun/core/_constant.py +236 -0
- wrfrun/core/_exec_db.py +105 -0
- wrfrun/core/_namelist.py +287 -0
- wrfrun/core/_record.py +178 -0
- wrfrun/core/_resource.py +172 -0
- wrfrun/core/base.py +136 -380
- wrfrun/core/core.py +196 -0
- wrfrun/core/error.py +35 -2
- wrfrun/core/replay.py +10 -96
- wrfrun/core/server.py +74 -32
- wrfrun/core/type.py +171 -0
- wrfrun/data.py +312 -149
- wrfrun/extension/goos_sst/__init__.py +2 -2
- wrfrun/extension/goos_sst/core.py +9 -14
- wrfrun/extension/goos_sst/res/__init__.py +0 -1
- wrfrun/extension/goos_sst/utils.py +50 -44
- wrfrun/extension/littler/core.py +105 -88
- wrfrun/extension/utils.py +5 -3
- wrfrun/log.py +117 -0
- wrfrun/model/__init__.py +11 -7
- wrfrun/model/constants.py +52 -0
- wrfrun/model/palm/__init__.py +30 -0
- wrfrun/model/palm/core.py +145 -0
- wrfrun/model/palm/namelist.py +33 -0
- wrfrun/model/plot.py +99 -114
- wrfrun/model/type.py +116 -0
- wrfrun/model/utils.py +9 -19
- wrfrun/model/wrf/__init__.py +4 -9
- wrfrun/model/wrf/core.py +262 -165
- wrfrun/model/wrf/exec_wrap.py +13 -12
- wrfrun/model/wrf/geodata.py +116 -99
- wrfrun/model/wrf/log.py +103 -0
- wrfrun/model/wrf/namelist.py +92 -76
- wrfrun/model/wrf/plot.py +102 -0
- wrfrun/model/wrf/scheme.py +108 -52
- wrfrun/model/wrf/utils.py +39 -24
- wrfrun/model/wrf/vtable.py +42 -7
- wrfrun/plot/__init__.py +20 -0
- wrfrun/plot/wps.py +90 -73
- wrfrun/res/__init__.py +115 -5
- wrfrun/res/config/config.template.toml +15 -0
- wrfrun/res/config/palm.template.toml +23 -0
- wrfrun/run.py +121 -77
- wrfrun/scheduler/__init__.py +1 -0
- wrfrun/scheduler/lsf.py +4 -1
- wrfrun/scheduler/pbs.py +4 -1
- wrfrun/scheduler/script.py +19 -5
- wrfrun/scheduler/slurm.py +4 -1
- wrfrun/scheduler/utils.py +14 -2
- wrfrun/utils.py +88 -199
- wrfrun/workspace/__init__.py +8 -5
- wrfrun/workspace/core.py +21 -11
- wrfrun/workspace/palm.py +137 -0
- wrfrun/workspace/wrf.py +59 -14
- wrfrun-0.3.0.dist-info/METADATA +240 -0
- wrfrun-0.3.0.dist-info/RECORD +78 -0
- wrfrun/core/config.py +0 -767
- wrfrun/model/base.py +0 -14
- wrfrun-0.1.9.dist-info/METADATA +0 -68
- wrfrun-0.1.9.dist-info/RECORD +0 -62
- {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
- {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
wrfrun/data.py
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.data
|
|
3
|
+
###########
|
|
4
|
+
|
|
5
|
+
.. autosummary::
|
|
6
|
+
:toctree: generated/
|
|
7
|
+
|
|
8
|
+
ERA5CONFIG
|
|
9
|
+
_check_variables_and_datasets
|
|
10
|
+
_check_pressure_level
|
|
11
|
+
find_era5_data
|
|
12
|
+
prepare_wps_input_data
|
|
13
|
+
download_data
|
|
14
|
+
"""
|
|
15
|
+
|
|
1
16
|
from datetime import datetime
|
|
2
17
|
from os import makedirs
|
|
3
|
-
from os.path import
|
|
4
|
-
from typing import
|
|
18
|
+
from os.path import dirname, exists
|
|
19
|
+
from typing import List, Literal, Tuple, Union
|
|
5
20
|
|
|
6
21
|
from pandas import date_range
|
|
7
|
-
# from seafog import goos_sst_find_data
|
|
8
22
|
|
|
9
|
-
from .core
|
|
10
|
-
from .
|
|
23
|
+
from .core import WRFRUN
|
|
24
|
+
from .log import logger
|
|
25
|
+
|
|
26
|
+
# from seafog import goos_sst_find_data
|
|
11
27
|
|
|
12
28
|
# lazy initialize
|
|
13
29
|
CDS_CLIENT = None
|
|
@@ -16,6 +32,68 @@ CDS_CLIENT = None
|
|
|
16
32
|
class ERA5CONFIG:
|
|
17
33
|
"""
|
|
18
34
|
A class to store parameters we will use to download ERA5 data from cdsapi.
|
|
35
|
+
|
|
36
|
+
.. py:attribute:: DATASET_ERA5_SINGLE_LEVEL
|
|
37
|
+
:type: str
|
|
38
|
+
:value: "reanalysis-era5-single-levels"
|
|
39
|
+
|
|
40
|
+
ERA5 dataset type.
|
|
41
|
+
|
|
42
|
+
.. py:attribute:: DATASET_ERA5_PRESSURE_LEVEL
|
|
43
|
+
:type: str
|
|
44
|
+
:value: "reanalysis-era5-pressure-levels"
|
|
45
|
+
|
|
46
|
+
ERA5 dataset type.
|
|
47
|
+
|
|
48
|
+
.. py:attribute:: TYPE_REANALYSIS
|
|
49
|
+
:type: str
|
|
50
|
+
:value: "reanalysis"
|
|
51
|
+
|
|
52
|
+
ERA5 product type.
|
|
53
|
+
|
|
54
|
+
.. py:attribute:: FORMAT_NETCDF
|
|
55
|
+
:type: str
|
|
56
|
+
:value: "netcdf"
|
|
57
|
+
|
|
58
|
+
ERA5 data format type.
|
|
59
|
+
|
|
60
|
+
.. py:attribute:: FORMAT_GRIB
|
|
61
|
+
:type: str
|
|
62
|
+
:value: "grib"
|
|
63
|
+
|
|
64
|
+
ERA5 data format type.
|
|
65
|
+
|
|
66
|
+
.. py:attribute:: DOWNLOAD_ZIP
|
|
67
|
+
:type: str
|
|
68
|
+
:value: "zip"
|
|
69
|
+
|
|
70
|
+
ERA5 download type.
|
|
71
|
+
|
|
72
|
+
.. py:attribute:: DOWNLOAD_UNZIP
|
|
73
|
+
:type: str
|
|
74
|
+
:value: "unarchived"
|
|
75
|
+
|
|
76
|
+
ERA5 download type.
|
|
77
|
+
|
|
78
|
+
.. py:attribute:: PRESSURE_LEVEL
|
|
79
|
+
:type: list
|
|
80
|
+
|
|
81
|
+
ERA5 available pressure levels.
|
|
82
|
+
|
|
83
|
+
.. py:attribute:: VARIABLE_*
|
|
84
|
+
:type: str
|
|
85
|
+
|
|
86
|
+
ERA5 variable names. Please check the code to see available values (too many to list here).
|
|
87
|
+
|
|
88
|
+
.. py:attribute:: NAME_MAP
|
|
89
|
+
:type: dict
|
|
90
|
+
|
|
91
|
+
Dictionary maps variable to its name in data.
|
|
92
|
+
|
|
93
|
+
.. py:attribute:: TYPE_MAP
|
|
94
|
+
:type: dict
|
|
95
|
+
|
|
96
|
+
Dictionary to distinguish between two types of data.
|
|
19
97
|
"""
|
|
20
98
|
|
|
21
99
|
# dataset name
|
|
@@ -35,19 +113,43 @@ class ERA5CONFIG:
|
|
|
35
113
|
|
|
36
114
|
# all level
|
|
37
115
|
PRESSURE_LEVEL = [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
116
|
+
"1",
|
|
117
|
+
"2",
|
|
118
|
+
"3",
|
|
119
|
+
"5",
|
|
120
|
+
"7",
|
|
121
|
+
"10",
|
|
122
|
+
"20",
|
|
123
|
+
"30",
|
|
124
|
+
"50",
|
|
125
|
+
"70",
|
|
126
|
+
"100",
|
|
127
|
+
"125",
|
|
128
|
+
"150",
|
|
129
|
+
"175",
|
|
130
|
+
"200",
|
|
131
|
+
"225",
|
|
132
|
+
"250",
|
|
133
|
+
"300",
|
|
134
|
+
"350",
|
|
135
|
+
"400",
|
|
136
|
+
"450",
|
|
137
|
+
"500",
|
|
138
|
+
"550",
|
|
139
|
+
"600",
|
|
140
|
+
"650",
|
|
141
|
+
"700",
|
|
142
|
+
"750",
|
|
143
|
+
"775",
|
|
144
|
+
"800",
|
|
145
|
+
"825",
|
|
146
|
+
"850",
|
|
147
|
+
"875",
|
|
148
|
+
"900",
|
|
149
|
+
"925",
|
|
150
|
+
"950",
|
|
151
|
+
"975",
|
|
152
|
+
"1000",
|
|
51
153
|
]
|
|
52
154
|
|
|
53
155
|
# variable name
|
|
@@ -101,7 +203,7 @@ class ERA5CONFIG:
|
|
|
101
203
|
"volumetric_soil_water_layer_1": "swvl1",
|
|
102
204
|
"volumetric_soil_water_layer_2": "swvl2",
|
|
103
205
|
"volumetric_soil_water_layer_3": "swvl3",
|
|
104
|
-
"volumetric_soil_water_layer_4": "swvl4"
|
|
206
|
+
"volumetric_soil_water_layer_4": "swvl4",
|
|
105
207
|
}
|
|
106
208
|
|
|
107
209
|
# use a dict to distinguish between two types of data
|
|
@@ -124,8 +226,7 @@ class ERA5CONFIG:
|
|
|
124
226
|
"volumetric_soil_water_layer_1",
|
|
125
227
|
"volumetric_soil_water_layer_2",
|
|
126
228
|
"volumetric_soil_water_layer_3",
|
|
127
|
-
"volumetric_soil_water_layer_4"
|
|
128
|
-
|
|
229
|
+
"volumetric_soil_water_layer_4",
|
|
129
230
|
),
|
|
130
231
|
"reanalysis-era5-pressure-levels": (
|
|
131
232
|
"specific_humidity",
|
|
@@ -133,20 +234,21 @@ class ERA5CONFIG:
|
|
|
133
234
|
"v_component_of_wind",
|
|
134
235
|
"geopotential",
|
|
135
236
|
"relative_humidity",
|
|
136
|
-
"temperature"
|
|
137
|
-
)
|
|
237
|
+
"temperature",
|
|
238
|
+
),
|
|
138
239
|
}
|
|
139
240
|
|
|
140
241
|
|
|
141
242
|
def _check_variables_and_datasets(variables: Union[str, Tuple[str, ...]], dataset: str) -> bool:
|
|
142
|
-
"""
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
243
|
+
"""
|
|
244
|
+
Check if variables and datasets correspond.
|
|
245
|
+
|
|
246
|
+
:param variables: Variables type.
|
|
247
|
+
:type variables: Union[str, Tuple[str, ...]]
|
|
248
|
+
:param dataset: Dataset type.
|
|
249
|
+
:type dataset: str
|
|
250
|
+
:return: If check passed, return ``True``, else ``False``.
|
|
251
|
+
:rtype: bool
|
|
150
252
|
"""
|
|
151
253
|
if isinstance(variables, str):
|
|
152
254
|
if variables in ERA5CONFIG.TYPE_MAP[dataset]:
|
|
@@ -162,28 +264,52 @@ def _check_variables_and_datasets(variables: Union[str, Tuple[str, ...]], datase
|
|
|
162
264
|
|
|
163
265
|
|
|
164
266
|
def _check_pressure_level(pressure_level: Union[str, List[str]]) -> bool:
|
|
165
|
-
"""
|
|
166
|
-
|
|
167
|
-
Args:
|
|
168
|
-
pressure_level (int | list[int]): A integer value or a list contains pressure values
|
|
267
|
+
"""
|
|
268
|
+
Check pressure level.
|
|
169
269
|
|
|
170
|
-
|
|
171
|
-
|
|
270
|
+
:param pressure_level: A integer value or a list contains pressure values.
|
|
271
|
+
:type pressure_level: Union[str, List[str]]
|
|
272
|
+
:return: If check passed, return ``True``, else ``False``.
|
|
273
|
+
:rtype: bool
|
|
172
274
|
"""
|
|
173
275
|
valid_pressure_level = [
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
276
|
+
"1",
|
|
277
|
+
"2",
|
|
278
|
+
"3",
|
|
279
|
+
"5",
|
|
280
|
+
"7",
|
|
281
|
+
"10",
|
|
282
|
+
"20",
|
|
283
|
+
"30",
|
|
284
|
+
"50",
|
|
285
|
+
"70",
|
|
286
|
+
"100",
|
|
287
|
+
"125",
|
|
288
|
+
"150",
|
|
289
|
+
"175",
|
|
290
|
+
"200",
|
|
291
|
+
"225",
|
|
292
|
+
"250",
|
|
293
|
+
"300",
|
|
294
|
+
"350",
|
|
295
|
+
"400",
|
|
296
|
+
"450",
|
|
297
|
+
"500",
|
|
298
|
+
"550",
|
|
299
|
+
"600",
|
|
300
|
+
"650",
|
|
301
|
+
"700",
|
|
302
|
+
"750",
|
|
303
|
+
"775",
|
|
304
|
+
"800",
|
|
305
|
+
"825",
|
|
306
|
+
"850",
|
|
307
|
+
"875",
|
|
308
|
+
"900",
|
|
309
|
+
"925",
|
|
310
|
+
"950",
|
|
311
|
+
"975",
|
|
312
|
+
"1000",
|
|
187
313
|
]
|
|
188
314
|
|
|
189
315
|
for level in pressure_level:
|
|
@@ -193,32 +319,49 @@ def _check_pressure_level(pressure_level: Union[str, List[str]]) -> bool:
|
|
|
193
319
|
return True
|
|
194
320
|
|
|
195
321
|
|
|
196
|
-
def find_era5_data(
|
|
197
|
-
|
|
198
|
-
|
|
322
|
+
def find_era5_data(
|
|
323
|
+
date: Union[List[str], List[datetime]],
|
|
324
|
+
area: Tuple[int, int, int, int],
|
|
325
|
+
variables: Union[Tuple[str, ...], str],
|
|
326
|
+
save_path: str,
|
|
327
|
+
product_type=ERA5CONFIG.TYPE_REANALYSIS,
|
|
328
|
+
data_format=ERA5CONFIG.FORMAT_NETCDF,
|
|
329
|
+
dataset=ERA5CONFIG.DATASET_ERA5_SINGLE_LEVEL,
|
|
330
|
+
download_format=ERA5CONFIG.DOWNLOAD_UNZIP,
|
|
331
|
+
pressure_level: Union[int, List[int], str, List[str], None] = None,
|
|
332
|
+
overwrite=False,
|
|
333
|
+
) -> str:
|
|
199
334
|
"""
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
335
|
+
Download data from ERA5.
|
|
336
|
+
|
|
337
|
+
:param date: List of date string or datetime object, UTC time.
|
|
338
|
+
:type date: Union[List[str], List[datetime]]
|
|
339
|
+
:param area: Range of longitude and latitude, ``[lon1, lon2, lat1, lat2]``.
|
|
340
|
+
:type area: Tuple[int, int, int, int]
|
|
341
|
+
:param variables: Variables to be download. Check :class:`ERA5CONFIG` for valid values.
|
|
342
|
+
:type variables: Union[Tuple[str, ...], str]
|
|
343
|
+
:param save_path: Data save path.
|
|
344
|
+
:type save_path: str
|
|
345
|
+
:param product_type: Product type. Check :class:`ERA5CONFIG` for valid values.
|
|
346
|
+
:type product_type: str
|
|
347
|
+
:param data_format: Data format. Check :class:`ERA5CONFIG` for valid values.
|
|
348
|
+
:type data_format: str
|
|
349
|
+
:param dataset: Dataset type. Check :class:`ERA5CONFIG` for valid values.
|
|
350
|
+
:type dataset: str
|
|
351
|
+
:param download_format: Download format. Check :class:`ERA5CONFIG` for valid values.
|
|
352
|
+
:type download_format: str
|
|
353
|
+
:param pressure_level: Pressure levels to be download. Check :class:`ERA5CONFIG` for valid values.
|
|
354
|
+
:type pressure_level: Union[int, List[int], str, List[str], None]
|
|
355
|
+
:param overwrite: If the data file exists, force to download it when ``overwrite==True``.
|
|
356
|
+
:type overwrite: bool
|
|
357
|
+
:return: Data path.
|
|
358
|
+
:rtype: str
|
|
215
359
|
"""
|
|
216
360
|
global CDS_CLIENT
|
|
217
361
|
|
|
218
362
|
# check variables and datasets
|
|
219
363
|
if not _check_variables_and_datasets(variables, dataset):
|
|
220
|
-
logger.error(
|
|
221
|
-
f"Variables {variables} and dataset {dataset} doesn't correspond, check it")
|
|
364
|
+
logger.error(f"Variables {variables} and dataset {dataset} doesn't correspond, check it")
|
|
222
365
|
exit(1)
|
|
223
366
|
|
|
224
367
|
# check if we need to create directory
|
|
@@ -231,8 +374,10 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
|
|
|
231
374
|
|
|
232
375
|
# parse date
|
|
233
376
|
if isinstance(date[0], str):
|
|
234
|
-
date = [
|
|
235
|
-
|
|
377
|
+
date = [
|
|
378
|
+
datetime.strptime(_date, "%Y-%m-%d %H:%M") # type: ignore
|
|
379
|
+
for _date in date
|
|
380
|
+
]
|
|
236
381
|
year = list(set(_date.strftime("%Y") for _date in date)) # type: ignore
|
|
237
382
|
month = list(set(_date.strftime("%m") for _date in date)) # type: ignore
|
|
238
383
|
day = list(set(_date.strftime("%d") for _date in date)) # type: ignore
|
|
@@ -250,42 +395,40 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
|
|
|
250
395
|
|
|
251
396
|
# create params dict
|
|
252
397
|
params_dict = {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
398
|
+
"product_type": product_type,
|
|
399
|
+
"data_format": data_format,
|
|
400
|
+
"download_format": download_format,
|
|
401
|
+
"variable": variables,
|
|
402
|
+
"year": year,
|
|
403
|
+
"month": month,
|
|
404
|
+
"day": day,
|
|
405
|
+
"time": time,
|
|
406
|
+
"area": area,
|
|
262
407
|
}
|
|
263
408
|
|
|
264
409
|
# check if we need to add pressure_level to params dict
|
|
265
410
|
if dataset == ERA5CONFIG.DATASET_ERA5_PRESSURE_LEVEL:
|
|
266
411
|
if pressure_level is None:
|
|
267
|
-
logger.error(
|
|
268
|
-
f"You need to provide pressure levels to download data")
|
|
412
|
+
logger.error("You need to provide pressure levels to download data")
|
|
269
413
|
exit(1)
|
|
270
414
|
# convert value to str
|
|
271
415
|
if not isinstance(pressure_level, list):
|
|
272
|
-
pressure_level = [pressure_level]
|
|
416
|
+
pressure_level = [pressure_level] # type: ignore
|
|
273
417
|
if not isinstance(pressure_level[0], str): # type: ignore
|
|
274
|
-
pressure_level = [str(int(x))
|
|
275
|
-
for x in pressure_level] # type: ignore
|
|
418
|
+
pressure_level = [str(int(x)) for x in pressure_level] # type: ignore
|
|
276
419
|
# check
|
|
277
|
-
if _check_pressure_level(pressure_level):
|
|
420
|
+
if _check_pressure_level(pressure_level): # type: ignore
|
|
278
421
|
params_dict["pressure_level"] = pressure_level
|
|
279
422
|
else:
|
|
280
|
-
logger.error(
|
|
281
|
-
f"You have passed wrong pressure level to download data, check it")
|
|
423
|
+
logger.error("You have passed wrong pressure level to download data, check it")
|
|
282
424
|
exit(1)
|
|
283
425
|
|
|
284
426
|
# download data
|
|
285
|
-
logger.info(f"Downloading data to {save_path}, it may take several tens of minutes, please wait...")
|
|
427
|
+
logger.info(f"Downloading data to '{save_path}', it may take several tens of minutes, please wait...")
|
|
286
428
|
|
|
287
429
|
if CDS_CLIENT is None:
|
|
288
430
|
import cdsapi
|
|
431
|
+
|
|
289
432
|
CDS_CLIENT = cdsapi.Client()
|
|
290
433
|
|
|
291
434
|
CDS_CLIENT.retrieve(dataset, params_dict, save_path)
|
|
@@ -294,35 +437,51 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
|
|
|
294
437
|
|
|
295
438
|
|
|
296
439
|
def prepare_wps_input_data(area: Tuple[int, int, int, int]):
|
|
297
|
-
"""
|
|
440
|
+
"""
|
|
441
|
+
Download essential data for WPS.
|
|
298
442
|
|
|
299
|
-
|
|
300
|
-
|
|
443
|
+
:param area: Range of longitude and latitude, ``[lon1, lon2, lat1, lat2]``.
|
|
444
|
+
:type area: Tuple[int, int, int, int]
|
|
301
445
|
"""
|
|
302
|
-
wrf_config =
|
|
446
|
+
wrf_config = WRFRUN.config.get_model_config("wrf")
|
|
303
447
|
# get start and end date from config
|
|
304
448
|
start_date = wrf_config["time"]["start_date"]
|
|
305
449
|
end_date = wrf_config["time"]["end_date"]
|
|
306
450
|
|
|
307
451
|
# remove second part
|
|
308
|
-
start_date = start_date
|
|
309
|
-
end_date = end_date
|
|
452
|
+
start_date = start_date.strftime("%Y-%m-%d %H:%M")
|
|
453
|
+
end_date = end_date.strftime("%Y-%m-%d %H:%M")
|
|
310
454
|
|
|
311
455
|
# get hour step
|
|
312
456
|
hour_step = wrf_config["time"]["input_data_interval"] // 3600
|
|
313
457
|
|
|
314
458
|
# get data save path
|
|
315
|
-
|
|
316
|
-
sst_save_path = wrf_config["near_goos_data_folder"]
|
|
459
|
+
data_save_path = WRFRUN.config.get_input_data_path()
|
|
317
460
|
|
|
318
461
|
# download data
|
|
319
|
-
logger.info(
|
|
320
|
-
download_data(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
462
|
+
logger.info("Download background data of surface level...")
|
|
463
|
+
download_data(
|
|
464
|
+
start_date,
|
|
465
|
+
end_date,
|
|
466
|
+
hour_step,
|
|
467
|
+
area,
|
|
468
|
+
f"{data_save_path}/surface.grib",
|
|
469
|
+
data_format="grib",
|
|
470
|
+
data_type="surface",
|
|
471
|
+
overwrite=True,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
logger.info("Download background data of pressure level...")
|
|
475
|
+
download_data(
|
|
476
|
+
start_date,
|
|
477
|
+
end_date,
|
|
478
|
+
hour_step,
|
|
479
|
+
area,
|
|
480
|
+
f"{data_save_path}/pressure.grib",
|
|
481
|
+
data_format="grib",
|
|
482
|
+
data_type="pressure",
|
|
483
|
+
overwrite=True,
|
|
484
|
+
)
|
|
326
485
|
|
|
327
486
|
# logger.info(f"Download NearGOOS data...")
|
|
328
487
|
# download_data(start_date, end_date, hour_step, area,
|
|
@@ -330,57 +489,61 @@ def prepare_wps_input_data(area: Tuple[int, int, int, int]):
|
|
|
330
489
|
|
|
331
490
|
|
|
332
491
|
def download_data(
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
492
|
+
start_date: str,
|
|
493
|
+
end_date: str,
|
|
494
|
+
hour_step: int,
|
|
495
|
+
area: Tuple[int, int, int, int],
|
|
496
|
+
save_path: str,
|
|
497
|
+
data_format: Literal["nc", "grib"] = "nc",
|
|
498
|
+
data_type: Literal["pressure", "surface"] = "pressure",
|
|
499
|
+
overwrite=False,
|
|
500
|
+
) -> str:
|
|
501
|
+
"""
|
|
502
|
+
Download essential data from ERA5.
|
|
503
|
+
|
|
504
|
+
:param start_date: Begin date, for example, ``"2022-05-19 12:00"``.
|
|
505
|
+
:type start_date: str
|
|
506
|
+
:param end_date: End date, for example, ``"2022-05-22 18:00"``.
|
|
507
|
+
:type end_date: str
|
|
508
|
+
:param hour_step: Hour step.
|
|
509
|
+
:type hour_step: int
|
|
510
|
+
:param area: Range of longitude and latitude, ``[lon1, lon2, lat1, lat2]``.
|
|
511
|
+
:type area: Tuple[int, int, int, int]
|
|
512
|
+
:param save_path: Data save path.
|
|
513
|
+
:type save_path: str
|
|
514
|
+
:param data_format: Download data format. Default is ``"nc"``.
|
|
515
|
+
:type data_format: Literal["nc", "grib"]
|
|
516
|
+
:param data_type: Download data type. Default is ``"pressure"``.
|
|
517
|
+
:param overwrite: If the data file exists, force to download it when ``overwrite==True``.
|
|
518
|
+
:return: Data path.
|
|
519
|
+
:rtype: str
|
|
355
520
|
"""
|
|
356
521
|
# generate date list
|
|
357
|
-
date_list = date_range(
|
|
358
|
-
start_date, end_date, freq=f"{hour_step}H"
|
|
359
|
-
).strftime("%Y-%m-%d %H:%M").to_list()
|
|
522
|
+
date_list = date_range(start_date, end_date, freq=f"{hour_step}H").strftime("%Y-%m-%d %H:%M").to_list()
|
|
360
523
|
|
|
361
524
|
# check format
|
|
362
525
|
if data_format == "nc":
|
|
363
|
-
|
|
526
|
+
_data_format = ERA5CONFIG.FORMAT_NETCDF
|
|
364
527
|
elif data_format == "grib":
|
|
365
|
-
|
|
528
|
+
_data_format = ERA5CONFIG.FORMAT_GRIB
|
|
366
529
|
else:
|
|
367
|
-
logger.error(f"Wrong data format: {
|
|
530
|
+
logger.error(f"Wrong data format: {_data_format}")
|
|
368
531
|
raise KeyError
|
|
369
532
|
|
|
370
533
|
# check data type
|
|
371
534
|
if data_type == "pressure":
|
|
372
|
-
|
|
535
|
+
_data_type = ERA5CONFIG.DATASET_ERA5_PRESSURE_LEVEL
|
|
373
536
|
variables = (
|
|
374
537
|
ERA5CONFIG.VARIABLE_GEOPOTENTIAL,
|
|
375
538
|
ERA5CONFIG.VARIABLE_RELATIVE_HUMIDITY,
|
|
376
539
|
ERA5CONFIG.VARIABLE_SPECIFIC_HUMIDITY,
|
|
377
540
|
ERA5CONFIG.VARIABLE_TEMPERATURE,
|
|
378
541
|
ERA5CONFIG.VARIABLE_U_WIND,
|
|
379
|
-
ERA5CONFIG.VARIABLE_V_WIND
|
|
542
|
+
ERA5CONFIG.VARIABLE_V_WIND,
|
|
380
543
|
)
|
|
381
544
|
pressure_level = ERA5CONFIG.PRESSURE_LEVEL
|
|
382
545
|
elif data_type == "surface":
|
|
383
|
-
|
|
546
|
+
_data_type = ERA5CONFIG.DATASET_ERA5_SINGLE_LEVEL
|
|
384
547
|
variables = (
|
|
385
548
|
ERA5CONFIG.VARIABLE_SURFACE_PRESSURE,
|
|
386
549
|
ERA5CONFIG.VARIABLE_MEAN_SEA_LEVEL_PRESSURE,
|
|
@@ -399,25 +562,25 @@ def download_data(
|
|
|
399
562
|
ERA5CONFIG.VARIABLE_VOLUMETRIC_SOIL_WATER_LAYER_3,
|
|
400
563
|
ERA5CONFIG.VARIABLE_VOLUMETRIC_SOIL_WATER_LAYER_4,
|
|
401
564
|
ERA5CONFIG.VARIABLE_SNOW_DEPTH,
|
|
402
|
-
ERA5CONFIG.VARIABLE_SNOW_DENSITY
|
|
565
|
+
ERA5CONFIG.VARIABLE_SNOW_DENSITY,
|
|
403
566
|
)
|
|
404
567
|
pressure_level = None
|
|
405
|
-
elif data_type == "goos":
|
|
406
|
-
logger.warning(f"NEAR-GOOS SST data hasn't been supported yet")
|
|
407
|
-
# download sst data
|
|
408
|
-
# for _date in date_list:
|
|
409
|
-
# _ = goos_sst_find_data(_date, save_path=save_path)
|
|
410
|
-
|
|
411
|
-
return ""
|
|
412
568
|
else:
|
|
413
|
-
logger.error(f"Wrong data type: {
|
|
569
|
+
logger.error(f"Wrong data type: {_data_type}")
|
|
414
570
|
raise KeyError
|
|
415
571
|
|
|
416
572
|
# download data
|
|
417
|
-
return find_era5_data(
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
573
|
+
return find_era5_data(
|
|
574
|
+
date=date_list,
|
|
575
|
+
area=area,
|
|
576
|
+
variables=variables,
|
|
577
|
+
save_path=save_path,
|
|
578
|
+
data_format=_data_format,
|
|
579
|
+
dataset=_data_type,
|
|
580
|
+
pressure_level=pressure_level,
|
|
581
|
+
download_format=ERA5CONFIG.DOWNLOAD_UNZIP,
|
|
582
|
+
overwrite=overwrite,
|
|
583
|
+
)
|
|
421
584
|
|
|
422
585
|
|
|
423
586
|
__all__ = ["find_era5_data", "ERA5CONFIG", "download_data", "prepare_wps_input_data"]
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
wrfrun.extension.goos_sst
|
|
3
3
|
#########################
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Extension help user create a GRIB file from ERA5 skin temperature (SKT) data and NEAR-GOOS sea surface temperature (SST) data.
|
|
6
6
|
|
|
7
7
|
============================================= =============================================
|
|
8
8
|
:doc:`core </api/extension.goos_sst.core>` Core functionality submodule.
|
|
@@ -50,7 +50,7 @@ The code snap below shows you how to use this extension.
|
|
|
50
50
|
if __name__ == '__main__':
|
|
51
51
|
era5_data_path = "data/ear5-reanalysis-data.grib"
|
|
52
52
|
merge_era5_goos_sst_grib(era5_data_path, "data/near-goos-data.grib")
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
Please check :func:`core.merge_era5_goos_sst_grib` for more information.
|
|
55
55
|
|
|
56
56
|
.. toctree::
|