wrfrun 0.2.0__py3-none-any.whl → 0.3.1__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 +96 -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.1.dist-info/METADATA +239 -0
  60. wrfrun-0.3.1.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.1.dist-info}/WHEEL +0 -0
  66. {wrfrun-0.2.0.dist-info → wrfrun-0.3.1.dist-info}/entry_points.txt +0 -0
wrfrun/data.py CHANGED
@@ -1,12 +1,27 @@
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
18
  from os.path import dirname, exists
4
- from typing import List, Tuple, Union
19
+ from typing import List, Literal, Tuple, Union
5
20
 
6
21
  from pandas import date_range
7
22
 
8
- from .core import get_wrfrun_config
9
- from .utils import logger
23
+ from .core import WRFRUN
24
+ from .log import logger
10
25
 
11
26
  # from seafog import goos_sst_find_data
12
27
 
@@ -17,6 +32,68 @@ CDS_CLIENT = None
17
32
  class ERA5CONFIG:
18
33
  """
19
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.
20
97
  """
21
98
 
22
99
  # dataset name
@@ -36,19 +113,43 @@ class ERA5CONFIG:
36
113
 
37
114
  # all level
38
115
  PRESSURE_LEVEL = [
39
- '1', '2', '3',
40
- '5', '7', '10',
41
- '20', '30', '50',
42
- '70', '100', '125',
43
- '150', '175', '200',
44
- '225', '250', '300',
45
- '350', '400', '450',
46
- '500', '550', '600',
47
- '650', '700', '750',
48
- '775', '800', '825',
49
- '850', '875', '900',
50
- '925', '950', '975',
51
- '1000',
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",
52
153
  ]
53
154
 
54
155
  # variable name
@@ -102,7 +203,7 @@ class ERA5CONFIG:
102
203
  "volumetric_soil_water_layer_1": "swvl1",
103
204
  "volumetric_soil_water_layer_2": "swvl2",
104
205
  "volumetric_soil_water_layer_3": "swvl3",
105
- "volumetric_soil_water_layer_4": "swvl4"
206
+ "volumetric_soil_water_layer_4": "swvl4",
106
207
  }
107
208
 
108
209
  # use a dict to distinguish between two types of data
@@ -125,8 +226,7 @@ class ERA5CONFIG:
125
226
  "volumetric_soil_water_layer_1",
126
227
  "volumetric_soil_water_layer_2",
127
228
  "volumetric_soil_water_layer_3",
128
- "volumetric_soil_water_layer_4"
129
-
229
+ "volumetric_soil_water_layer_4",
130
230
  ),
131
231
  "reanalysis-era5-pressure-levels": (
132
232
  "specific_humidity",
@@ -134,20 +234,21 @@ class ERA5CONFIG:
134
234
  "v_component_of_wind",
135
235
  "geopotential",
136
236
  "relative_humidity",
137
- "temperature"
138
- )
237
+ "temperature",
238
+ ),
139
239
  }
140
240
 
141
241
 
142
242
  def _check_variables_and_datasets(variables: Union[str, Tuple[str, ...]], dataset: str) -> bool:
143
- """Check if variables and datasets correspond
144
-
145
- Args:
146
- variables (str | tuple[str]): Variables type
147
- dataset (str): Dataset type
148
-
149
- Returns:
150
- bool: If check passed, return True, else False
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
151
252
  """
152
253
  if isinstance(variables, str):
153
254
  if variables in ERA5CONFIG.TYPE_MAP[dataset]:
@@ -163,28 +264,52 @@ def _check_variables_and_datasets(variables: Union[str, Tuple[str, ...]], datase
163
264
 
164
265
 
165
266
  def _check_pressure_level(pressure_level: Union[str, List[str]]) -> bool:
166
- """Check pressure level
167
-
168
- Args:
169
- pressure_level (int | list[int]): A integer value or a list contains pressure values
267
+ """
268
+ Check pressure level.
170
269
 
171
- Returns:
172
- bool: If check passed, return True, else False
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
173
274
  """
174
275
  valid_pressure_level = [
175
- '1', '2', '3',
176
- '5', '7', '10',
177
- '20', '30', '50',
178
- '70', '100', '125',
179
- '150', '175', '200',
180
- '225', '250', '300',
181
- '350', '400', '450',
182
- '500', '550', '600',
183
- '650', '700', '750',
184
- '775', '800', '825',
185
- '850', '875', '900',
186
- '925', '950', '975',
187
- '1000',
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",
188
313
  ]
189
314
 
190
315
  for level in pressure_level:
@@ -194,32 +319,49 @@ def _check_pressure_level(pressure_level: Union[str, List[str]]) -> bool:
194
319
  return True
195
320
 
196
321
 
197
- def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int, int, int], variables: Union[Tuple[str, ...], str], save_path: str,
198
- product_type=ERA5CONFIG.TYPE_REANALYSIS, data_format=ERA5CONFIG.FORMAT_NETCDF, dataset=ERA5CONFIG.DATASET_ERA5_SINGLE_LEVEL,
199
- download_format=ERA5CONFIG.DOWNLOAD_UNZIP, pressure_level: Union[int, List[int], str, List[str], None] = None, overwrite=False) -> str:
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:
200
334
  """
201
- download era5 data
202
- Args:
203
- date: data date, string (for example, `2020-03-25 00:00`) or datetime object, UTC time
204
- area: range of longitude and latitude, `[lon1, lon2, lat1, lat2]`
205
- variables: variables, tuple of str or single string
206
- save_path: save file path
207
- product_type: product type, default is reanalysis
208
- data_format: data format, default is netcdf
209
- dataset: dataset type, default is reanalysis-era5-single-levels
210
- download_format: zip or unarchived.
211
- pressure_level: pressure levels.
212
- overwrite (bool): If the data file exists, force to download it when `overwrite=True`
213
-
214
- Returns: data path
215
-
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
216
359
  """
217
360
  global CDS_CLIENT
218
361
 
219
362
  # check variables and datasets
220
363
  if not _check_variables_and_datasets(variables, dataset):
221
- logger.error(
222
- 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")
223
365
  exit(1)
224
366
 
225
367
  # check if we need to create directory
@@ -232,8 +374,10 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
232
374
 
233
375
  # parse date
234
376
  if isinstance(date[0], str):
235
- date = [datetime.strptime(_date, "%Y-%m-%d %H:%M") # type: ignore
236
- for _date in date]
377
+ date = [
378
+ datetime.strptime(_date, "%Y-%m-%d %H:%M") # type: ignore
379
+ for _date in date
380
+ ]
237
381
  year = list(set(_date.strftime("%Y") for _date in date)) # type: ignore
238
382
  month = list(set(_date.strftime("%m") for _date in date)) # type: ignore
239
383
  day = list(set(_date.strftime("%d") for _date in date)) # type: ignore
@@ -251,15 +395,15 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
251
395
 
252
396
  # create params dict
253
397
  params_dict = {
254
- 'product_type': product_type,
255
- 'data_format': data_format,
256
- 'download_format': download_format,
257
- 'variable': variables,
258
- 'year': year,
259
- 'month': month,
260
- 'day': day,
261
- 'time': time,
262
- 'area': area,
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,
263
407
  }
264
408
 
265
409
  # check if we need to add pressure_level to params dict
@@ -269,12 +413,11 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
269
413
  exit(1)
270
414
  # convert value to str
271
415
  if not isinstance(pressure_level, list):
272
- pressure_level = [pressure_level] # type: ignore
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): # type: ignore
420
+ if _check_pressure_level(pressure_level): # type: ignore
278
421
  params_dict["pressure_level"] = pressure_level
279
422
  else:
280
423
  logger.error("You have passed wrong pressure level to download data, check it")
@@ -285,6 +428,7 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
285
428
 
286
429
  if CDS_CLIENT is None:
287
430
  import cdsapi
431
+
288
432
  CDS_CLIENT = cdsapi.Client()
289
433
 
290
434
  CDS_CLIENT.retrieve(dataset, params_dict, save_path)
@@ -293,12 +437,13 @@ def find_era5_data(date: Union[List[str], List[datetime]], area: Tuple[int, int,
293
437
 
294
438
 
295
439
  def prepare_wps_input_data(area: Tuple[int, int, int, int]):
296
- """Download essential data for WPS.
440
+ """
441
+ Download essential data for WPS.
297
442
 
298
- Args:
299
- area (Tuple[int, int, int, int]): Range of longitude and latitude, `[lon1, lon2, lat1, lat2]`.
443
+ :param area: Range of longitude and latitude, ``[lon1, lon2, lat1, lat2]``.
444
+ :type area: Tuple[int, int, int, int]
300
445
  """
301
- wrf_config = get_wrfrun_config().get_model_config("wrf")
446
+ wrf_config = WRFRUN.config.get_model_config("wrf")
302
447
  # get start and end date from config
303
448
  start_date = wrf_config["time"]["start_date"]
304
449
  end_date = wrf_config["time"]["end_date"]
@@ -311,16 +456,32 @@ def prepare_wps_input_data(area: Tuple[int, int, int, int]):
311
456
  hour_step = wrf_config["time"]["input_data_interval"] // 3600
312
457
 
313
458
  # get data save path
314
- data_save_path = get_wrfrun_config().get_input_data_path()
459
+ data_save_path = WRFRUN.config.get_input_data_path()
315
460
 
316
461
  # download data
317
- logger.info(f"Download background data of surface level...")
318
- download_data(start_date, end_date, hour_step, area, f"{data_save_path}/surface.grib",
319
- data_format="grib", data_type="surface", overwrite=True)
320
-
321
- logger.info(f"Download background data of pressure level...")
322
- download_data(start_date, end_date, hour_step, area, f"{data_save_path}/pressure.grib",
323
- data_format="grib", data_type="pressure", overwrite=True)
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
+ )
324
485
 
325
486
  # logger.info(f"Download NearGOOS data...")
326
487
  # download_data(start_date, end_date, hour_step, area,
@@ -328,57 +489,61 @@ def prepare_wps_input_data(area: Tuple[int, int, int, int]):
328
489
 
329
490
 
330
491
  def download_data(
331
- start_date: str,
332
- end_date: str,
333
- hour_step: int,
334
- area: Tuple[int, int, int, int],
335
- save_path: str,
336
- data_format="nc",
337
- data_type="pressure",
338
- overwrite=False) -> str:
339
- """Download essential data
340
-
341
- Args:
342
- start_date (str): Begin date, for example, "2022-05-19 12:00"
343
- end_date (str): End date, for example, "2022-05-22 18:00"
344
- hour_step (int): Hour step
345
- area (tuple): Range of longitude and latitude, `[lon1, lon2, lat1, lat2]`
346
- save_path (str): Data save path (era5 data) or data save folder path (goos sst)
347
- data_format (str): Download data format, "nc" or "grib". Default is "nc"
348
- data_type (str): Download data type, "pressure", "surface" or "goos". Default is "pressure".
349
- overwrite (bool): If the data file exists, force to download it when `overwrite=True`
350
-
351
- Returns:
352
- str: Data save path
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
353
520
  """
354
521
  # generate date list
355
- date_list = date_range(
356
- start_date, end_date, freq=f"{hour_step}H"
357
- ).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()
358
523
 
359
524
  # check format
360
525
  if data_format == "nc":
361
- data_format = ERA5CONFIG.FORMAT_NETCDF
526
+ _data_format = ERA5CONFIG.FORMAT_NETCDF
362
527
  elif data_format == "grib":
363
- data_format = ERA5CONFIG.FORMAT_GRIB
528
+ _data_format = ERA5CONFIG.FORMAT_GRIB
364
529
  else:
365
- logger.error(f"Wrong data format: {data_format}")
530
+ logger.error(f"Wrong data format: {_data_format}")
366
531
  raise KeyError
367
532
 
368
533
  # check data type
369
534
  if data_type == "pressure":
370
- data_type = ERA5CONFIG.DATASET_ERA5_PRESSURE_LEVEL
535
+ _data_type = ERA5CONFIG.DATASET_ERA5_PRESSURE_LEVEL
371
536
  variables = (
372
537
  ERA5CONFIG.VARIABLE_GEOPOTENTIAL,
373
538
  ERA5CONFIG.VARIABLE_RELATIVE_HUMIDITY,
374
539
  ERA5CONFIG.VARIABLE_SPECIFIC_HUMIDITY,
375
540
  ERA5CONFIG.VARIABLE_TEMPERATURE,
376
541
  ERA5CONFIG.VARIABLE_U_WIND,
377
- ERA5CONFIG.VARIABLE_V_WIND
542
+ ERA5CONFIG.VARIABLE_V_WIND,
378
543
  )
379
544
  pressure_level = ERA5CONFIG.PRESSURE_LEVEL
380
545
  elif data_type == "surface":
381
- data_type = ERA5CONFIG.DATASET_ERA5_SINGLE_LEVEL
546
+ _data_type = ERA5CONFIG.DATASET_ERA5_SINGLE_LEVEL
382
547
  variables = (
383
548
  ERA5CONFIG.VARIABLE_SURFACE_PRESSURE,
384
549
  ERA5CONFIG.VARIABLE_MEAN_SEA_LEVEL_PRESSURE,
@@ -397,25 +562,25 @@ def download_data(
397
562
  ERA5CONFIG.VARIABLE_VOLUMETRIC_SOIL_WATER_LAYER_3,
398
563
  ERA5CONFIG.VARIABLE_VOLUMETRIC_SOIL_WATER_LAYER_4,
399
564
  ERA5CONFIG.VARIABLE_SNOW_DEPTH,
400
- ERA5CONFIG.VARIABLE_SNOW_DENSITY
565
+ ERA5CONFIG.VARIABLE_SNOW_DENSITY,
401
566
  )
402
567
  pressure_level = None
403
- elif data_type == "goos":
404
- logger.warning(f"NEAR-GOOS SST data hasn't been supported yet")
405
- # download sst data
406
- # for _date in date_list:
407
- # _ = goos_sst_find_data(_date, save_path=save_path)
408
-
409
- return ""
410
568
  else:
411
- logger.error(f"Wrong data type: {data_type}")
569
+ logger.error(f"Wrong data type: {_data_type}")
412
570
  raise KeyError
413
571
 
414
572
  # download data
415
- return find_era5_data(date=date_list, area=area, variables=variables, # type: ignore
416
- save_path=save_path, data_format=data_format,
417
- dataset=data_type, pressure_level=pressure_level, # type: ignore
418
- download_format=ERA5CONFIG.DOWNLOAD_UNZIP, overwrite=overwrite)
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
+ )
419
584
 
420
585
 
421
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
- This extension can help you create a GRIB file from ERA5 skin temperature (SKT) data and NEAR-GOOS sea surface temperature (SST) data.
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::
@@ -7,19 +7,19 @@ Implementation of ``extension.goos_sst``'s core functionality.
7
7
 
8
8
  .. autosummary::
9
9
  :toctree: generated/
10
-
10
+
11
11
  merge_era5_goos_sst_grib
12
12
  """
13
13
 
14
14
  from os.path import dirname
15
15
 
16
- import cfgrib as cf
17
16
  import numpy as np
18
17
  from pandas import to_datetime
19
18
  from xarray import DataArray
20
19
 
20
+ from wrfrun.log import logger
21
+
21
22
  from .utils import create_sst_grib
22
- from wrfrun.utils import logger
23
23
 
24
24
 
25
25
  def merge_era5_goos_sst_grib(surface_grib_path: str, save_path: str, sst_data_save_path: str | None = None, resolution="low"):
@@ -41,6 +41,7 @@ def merge_era5_goos_sst_grib(surface_grib_path: str, save_path: str, sst_data_sa
41
41
  """
42
42
  # lazy import seafog to fix libcurl error in readthedocs
43
43
  # T^T
44
+ import cfgrib as cf
44
45
  from seafog import goos_sst_find_data, goos_sst_parser
45
46
 
46
47
  dataset_list = cf.open_datasets(surface_grib_path)
@@ -55,10 +56,10 @@ def merge_era5_goos_sst_grib(surface_grib_path: str, save_path: str, sst_data_sa
55
56
  logger.error(f"'skt' data not found in {surface_grib_path}")
56
57
  raise ValueError
57
58
 
58
- skt: DataArray = dataset["skt"] # type: ignore
59
+ skt: DataArray = dataset["skt"] # type: ignore
59
60
 
60
- longitude_start, longitude_end = skt["longitude"][0].data, skt["longitude"][-1].data # type: ignore
61
- latitude_start, latitude_end = skt["latitude"][-1].data, skt["latitude"][0].data # type: ignore
61
+ longitude_start, longitude_end = skt["longitude"][0].data, skt["longitude"][-1].data # type: ignore
62
+ latitude_start, latitude_end = skt["latitude"][-1].data, skt["latitude"][0].data # type: ignore
62
63
 
63
64
  data_time = skt["time"].to_numpy() # type: ignore
64
65
  data_time = to_datetime(data_time).strftime("%Y-%m-%d %H:%M")
@@ -95,14 +96,8 @@ def merge_era5_goos_sst_grib(surface_grib_path: str, save_path: str, sst_data_sa
95
96
  name="sst",
96
97
  data=sst,
97
98
  dims=["time", "latitude", "longitude"],
98
- coords={
99
- "time": skt["time"],
100
- "latitude": skt["latitude"],
101
- "longitude": skt["longitude"]
102
- }, attrs={
103
- "units": "K",
104
- "long_name": "Sea surface temperature"
105
- }
99
+ coords={"time": skt["time"], "latitude": skt["latitude"], "longitude": skt["longitude"]},
100
+ attrs={"units": "K", "long_name": "Sea surface temperature"},
106
101
  )
107
102
 
108
103
  create_sst_grib(sst, save_path=save_path)