wrfrun 0.1.7__py3-none-any.whl → 0.1.8__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.
@@ -0,0 +1,108 @@
1
+ """
2
+ wrfrun.extension.goos_sst.core
3
+ ##############################
4
+
5
+ Implementation of ``extension.goos_sst``'s core functionality.
6
+
7
+
8
+ .. autosummary::
9
+ :toctree: generated/
10
+
11
+ merge_era5_goos_sst_grib
12
+ """
13
+
14
+ from os.path import dirname
15
+
16
+ import cfgrib as cf
17
+ import numpy as np
18
+ from pandas import to_datetime
19
+ from seafog import goos_sst_find_data, goos_sst_parser
20
+ from xarray import DataArray
21
+
22
+ from .utils import create_sst_grib
23
+ from wrfrun.utils import logger
24
+
25
+
26
+ def merge_era5_goos_sst_grib(surface_grib_path: str, save_path: str, sst_data_save_path: str | None = None, resolution="low"):
27
+ """
28
+ This function reads ERA5 skin temperature (SKT) data from the GRIB file,
29
+ interpolates it to the same grib of NEAR-GOOS sea surface temperature (SST) data,
30
+ merges them and creates a new GRIB file with the new data.
31
+
32
+ :param surface_grib_path: GRIB file which contains SKT data.
33
+ :type surface_grib_path: str
34
+ :param save_path: Save path of the new GRIB file.
35
+ :type save_path: str
36
+ :param sst_data_save_path: Save path of downloaded NEAR-GOOS SST data.
37
+ If None, save data to the parent directory of ``save_path``.
38
+ :type sst_data_save_path: str | None
39
+ :param resolution: Resolution of downloaded NEAR-GOO SST data.
40
+ Please check ``seafog.goos_sst_find_data`` for more information.
41
+ :type resolution: str
42
+ """
43
+ dataset_list = cf.open_datasets(surface_grib_path)
44
+
45
+ dataset = None
46
+ for _ds in dataset_list:
47
+ if "skt" in _ds:
48
+ dataset = _ds
49
+ break
50
+
51
+ if dataset is None:
52
+ logger.error(f"'skt' data not found in {surface_grib_path}")
53
+ raise ValueError
54
+
55
+ skt: DataArray = dataset["skt"] # type: ignore
56
+
57
+ longitude_start, longitude_end = skt["longitude"][0].data, skt["longitude"][-1].data # type: ignore
58
+ latitude_start, latitude_end = skt["latitude"][-1].data, skt["latitude"][0].data # type: ignore
59
+
60
+ data_time = skt["time"].to_numpy() # type: ignore
61
+ data_time = to_datetime(data_time).strftime("%Y-%m-%d %H:%M")
62
+
63
+ if sst_data_save_path is None:
64
+ sst_data_save_path = dirname(save_path)
65
+
66
+ # read the first time data, so we can interpolate skt data to the same resolution as sst data.
67
+ _data = goos_sst_find_data(data_time[0], sst_data_save_path, resolution=resolution, show_progress=False)
68
+ _data = goos_sst_parser(_data, resolution=resolution)
69
+ _data = _data.loc[latitude_start:latitude_end, longitude_start:longitude_end]
70
+
71
+ skt = skt.interp({"longitude": _data["longitude"], "latitude": _data["latitude"]})
72
+ sst = np.zeros_like(skt)
73
+ temp_data = np.zeros_like(skt[0])
74
+
75
+ temp_data[:] = skt.to_numpy()[0]
76
+ index = ~np.isnan(_data.to_numpy())
77
+ temp_data[index] = _data.to_numpy()[index]
78
+ sst[0] = temp_data
79
+
80
+ # loop other time.
81
+ for time_index, _data_time in enumerate(data_time[1:], start=1):
82
+ _data = goos_sst_find_data(_data_time, sst_data_save_path, resolution=resolution, show_progress=False)
83
+ _data = goos_sst_parser(_data, resolution=resolution)
84
+ _data = _data.loc[latitude_start:latitude_end, longitude_start:longitude_end]
85
+
86
+ temp_data[:] = skt.to_numpy()[time_index]
87
+ index = ~np.isnan(_data.to_numpy())
88
+ temp_data[index] = _data.to_numpy()[index]
89
+ sst[time_index] = temp_data
90
+
91
+ sst = DataArray(
92
+ name="sst",
93
+ data=sst,
94
+ dims=["time", "latitude", "longitude"],
95
+ coords={
96
+ "time": skt["time"],
97
+ "latitude": skt["latitude"],
98
+ "longitude": skt["longitude"]
99
+ }, attrs={
100
+ "units": "K",
101
+ "long_name": "Sea surface temperature"
102
+ }
103
+ )
104
+
105
+ create_sst_grib(sst, save_path=save_path)
106
+
107
+
108
+ __all__ = ["merge_era5_goos_sst_grib"]
@@ -0,0 +1,7 @@
1
+ GRIB | Level| Level| Level| metgrid | metgrid | metgrid |
2
+ Code | Code | 1 | 2 | Name | Units | Description |
3
+ -----+------+------+------+----------+----------+------------------------------------------+
4
+ 34 | 1 | 0 | | SST | K | Sea-Surface Temperature |
5
+ -----+------+------+------+----------+----------+------------------------------------------+
6
+
7
+ # Vtable setting for GRIB file created by wrfrun.extension.sst
@@ -0,0 +1,9 @@
1
+ from os.path import abspath, dirname
2
+
3
+
4
+ _PATH = abspath(dirname(__file__))
5
+
6
+ VTABLE_ERA_GOOS_SST = f"{_PATH}/Vtable.ERA_GOOS_SST"
7
+
8
+
9
+ __all__ = ["VTABLE_ERA_GOOS_SST"]
@@ -0,0 +1,81 @@
1
+ from cfgrib.xarray_to_grib import to_grib
2
+ from numpy.dtypes import DateTime64DType
3
+ from pandas import to_datetime
4
+ from xarray import DataArray, Dataset
5
+
6
+ from wrfrun.utils import logger
7
+
8
+
9
+ def create_sst_grib(data: DataArray, save_path: str):
10
+ """
11
+ Create a dataset and save it to a GRIB file.
12
+
13
+ Args:
14
+ data: DataArray data, it should at least contain three dimensions: ``["time", "latitude", "longitude"]``.
15
+ save_path: GRIB file path.
16
+
17
+ """
18
+ # check the data's dimensions.
19
+ for _dim in ["time", "longitude", "latitude"]:
20
+ if _dim not in data.dims:
21
+ logger.error(f"Essential dimension '{_dim}' not found in data")
22
+ raise KeyError
23
+
24
+ if not isinstance(data["time"].dtype, DateTime64DType): # type: ignore
25
+ data = data.assign_coords(time=to_datetime(data["time"].data))
26
+
27
+ data = data.sortby(data["latitude"], ascending=False)
28
+
29
+ longitude_start, longitude_stop = data["longitude"][0].data, data["longitude"][-1].data
30
+ latitude_start, latitude_stop = data["latitude"][0].data, data["latitude"][-1].data
31
+ delta_longitude = data["longitude"][1].data - data["longitude"][0].data
32
+ delta_latitude = data["latitude"][0].data - data["latitude"][1].data
33
+ longitude_length = data["longitude"].size
34
+ latitude_length = data["latitude"].size
35
+ points_number = data.size
36
+
37
+ data = data.assign_attrs(**{
38
+ "units": "K",
39
+ "long_name": "Sea surface temperature",
40
+ "standard_name": "Sea surface temperature",
41
+ # The following keys and values will be used in GRIB.
42
+ "GRIB_paramId": 34,
43
+ "GRIB_shortName": "sst",
44
+ "GRIB_units": "K",
45
+ "GRIB_name": "Sea surface temperature",
46
+ "GRIB_stepUnits": 1,
47
+ "GRIB_stepType": "instant",
48
+ "GRIB_gridType": "regular_ll",
49
+ "GRIB_iDirectionIncrementInDegrees": delta_longitude,
50
+ "GRIB_iScanNegatively": 0,
51
+ "GRIB_jDirectionIncrementInDegrees": delta_latitude,
52
+ "GRIB_jScanPositively": 0,
53
+ "GRIB_latitudeOfFirstGridPointInDegrees": latitude_start,
54
+ "GRIB_latitudeOfLastGridPointInDegrees": latitude_stop,
55
+ "GRIB_longitudeOfFirstGridPointInDegrees": longitude_start,
56
+ "GRIB_longitudeOfLastGridPointInDegrees": longitude_stop,
57
+ "GRIB_Ny": latitude_length,
58
+ "GRIB_Nx": longitude_length,
59
+ "GRIB_typeOfLevel": "surface",
60
+ # The following keys and values can't be found at ECMWF websites.
61
+ "GRIB_cfName": "unknown",
62
+ "GRIB_cfVarName": "sst",
63
+ "GRIB_dataType": "an", # Analysis data, defined at https://codes.ecmwf.int/grib/format/mars/type/
64
+ "GRIB_gridDefinitionDescription": "Latitude/Longitude Grid",
65
+ # "GRIB_missingValue": -9999,
66
+ "GRIB_numberOfPoints": points_number,
67
+ "GRIB_totalNumber": 0,
68
+ "GRIB_uvRelativeToGird": 0
69
+ })
70
+
71
+ to_grib(
72
+ Dataset({
73
+ "sst": data
74
+ }, attrs={
75
+ "GRIB_centre": "ecmf",
76
+ "GRIB_edition": 1,
77
+ }), save_path
78
+ )
79
+
80
+
81
+ __all__ = ["create_sst_grib"]
wrfrun/model/plot.py CHANGED
@@ -5,8 +5,8 @@ from shutil import copyfile, move
5
5
  from wrfrun.core import WRFRUNConfig
6
6
  from wrfrun.res import EXT_NCL_PLOT_SCRIPT
7
7
  from wrfrun.utils import call_subprocess, check_path, logger
8
- from .wrf.namelist import prepare_wps_namelist
9
8
  from .base import NamelistName
9
+ from .wrf.namelist import prepare_wps_namelist
10
10
 
11
11
 
12
12
  def plot_domain_area():
wrfrun/model/wrf/core.py CHANGED
@@ -3,7 +3,7 @@ from os.path import abspath, basename, exists
3
3
  from shutil import copyfile, move, rmtree
4
4
  from typing import Optional
5
5
 
6
- from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistError, WRFRUNConfig, WRFRUNExecDB
6
+ from wrfrun.core import ExecutableBase, FileConfigDict, InputFileError, NamelistIDError, WRFRUNConfig, WRFRUNExecDB
7
7
  from wrfrun.utils import logger
8
8
  from ._metgrid import reconcile_namelist_metgrid
9
9
  from ._ndown import process_after_ndown
@@ -626,7 +626,7 @@ class DFI(ExecutableBase):
626
626
 
627
627
  if not WRFRUNConfig.register_custom_namelist_id("dfi"):
628
628
  logger.error("Can't register namelist for DFI.")
629
- raise NamelistError("Can't register namelist for DFI.")
629
+ raise NamelistIDError("Can't register namelist for DFI.")
630
630
  WRFRUNConfig.update_namelist(self.custom_config["namelist"], "dfi")
631
631
 
632
632
  def before_exec(self):
@@ -659,7 +659,7 @@ class DFI(ExecutableBase):
659
659
 
660
660
  if not WRFRUNConfig.register_custom_namelist_id("dfi"):
661
661
  logger.error("Can't register namelist for DFI.")
662
- raise NamelistError("Can't register namelist for DFI.")
662
+ raise NamelistIDError("Can't register namelist for DFI.")
663
663
 
664
664
  prepare_dfi_namelist()
665
665
 
@@ -79,18 +79,14 @@ def prepare_wps_namelist():
79
79
  "dy": wrf_config["domain"]["dy"],
80
80
  "ref_lat": wrf_config["domain"]["ref_lat"],
81
81
  "ref_lon": wrf_config["domain"]["ref_lon"],
82
+ "map_proj": wrf_config["domain"]["map_proj"],
83
+ "truelat1": wrf_config["domain"]["truelat1"],
84
+ "truelat2": wrf_config["domain"]["truelat2"],
82
85
  "stand_lon": wrf_config["domain"]["stand_lon"],
83
86
  "geog_data_path": wrf_config["geog_data_path"]
84
87
  }
85
88
  }
86
89
 
87
- # # use loop to process config of map_proj
88
- for key in wrf_config["domain"]["map_proj"]:
89
- if key == "name":
90
- update_value["geogrid"]["map_proj"] = wrf_config["domain"]["map_proj"][key]
91
- else:
92
- update_value["geogrid"][key] = wrf_config["domain"]["map_proj"][key]
93
-
94
90
  # # update namelist
95
91
  WRFRUNConfig.update_namelist(update_value, "wps")
96
92
 
@@ -308,4 +308,88 @@ class SchemeSurfaceLayer:
308
308
  return integer_label_map[key]
309
309
 
310
310
 
311
- __all__ = ["SchemeCumulus", "SchemeLandSurfaceModel", "SchemeLongWave", "SchemePBL", "SchemeShortWave", "SchemeSurfaceLayer"]
311
+ @dataclass()
312
+ class SchemeMicrophysics:
313
+ """
314
+ Microphysics schemes.
315
+ """
316
+ OFF = 0
317
+ KESSLER = 1
318
+ PURDUE_LIN = 2
319
+ WSM_3_CLASS_ICE = 3
320
+ WSM_5_CLASS = 4
321
+ FERRIER_ETA = 5
322
+ WSM_6_CLASS_GRAUPEL = 6
323
+ GODDARD_4_ICE = 7
324
+ THOMPSON_GRAUPEL = 8
325
+ MILBRANDT_YAU_2_MOMENT = 9
326
+ MORRISON_2_MOMENT = 10
327
+ CAM_V51_5_CLASS = 11
328
+ SBU_YLIN_5_CLASS = 13
329
+ WDM_5_CLASS = 14
330
+ HIGH_FERRIER_ADVECTION = 15
331
+ WDM_6_CLASS = 16
332
+ NSSL_2_MOMENT_4_ICE = 18
333
+ WSM7 = 24
334
+ WDM7 = 26
335
+ AEROSOL_AWARE_THOMPSON = 28
336
+ HUJI = 30
337
+ THOMPSON_HAIL_GRAUPEL_AEROSOL = 38
338
+ MORRISON_WITH_CESM_AEROSOL = 40
339
+ P3_1_ICE_1_MOMENT_QCLOUD = 50
340
+ P3_1_ICE_2_MOMENT_QCLOUD = 51
341
+ P3_2_ICE_2_MOMENT_QCLOUD = 52
342
+ P3_1_ICE_3_MOMENT_ICE_2_MOMENT_QCLOUD = 53
343
+ JENSEN_ISHMAEL = 55
344
+ NTU = 56
345
+
346
+ @classmethod
347
+ def get_scheme_id(cls, key: str = "lin"):
348
+ """Get corresponding integer label for microphysics scheme
349
+
350
+ Args:
351
+ key (str, optional): Name of microphysics scheme. Defaults to "PURDUE_LIN".
352
+ """
353
+ # Here is the map of scheme name and integer label in WRF
354
+ # Reference link: https://www2.mmm.ucar.edu/wrf/users/wrf_users_guide/build/html/namelist_variables.html
355
+ integer_label_map = {
356
+ "off": cls.OFF,
357
+ "kessler": cls.KESSLER,
358
+ "lin": cls.PURDUE_LIN,
359
+ "wsm3": cls.WSM_3_CLASS_ICE,
360
+ "wsm5": cls.WSM_5_CLASS,
361
+ "ferrier": cls.FERRIER_ETA,
362
+ "wsm6": cls.WDM_6_CLASS,
363
+ "goddard4": cls.GODDARD_4_ICE,
364
+ "thompson": cls.THOMPSON_GRAUPEL,
365
+ "milbrandt": cls.MILBRANDT_YAU_2_MOMENT,
366
+ "morrison2": cls.MORRISON_2_MOMENT,
367
+ "cam": cls.CAM_V51_5_CLASS,
368
+ "sbu": cls.SBU_YLIN_5_CLASS,
369
+ "wdm5": cls.WDM_5_CLASS,
370
+ "high_ferrier": cls.HIGH_FERRIER_ADVECTION,
371
+ "wdm6": cls.WDM_6_CLASS,
372
+ "nssl": cls.NSSL_2_MOMENT_4_ICE,
373
+ "wsm7": cls.WSM7,
374
+ "wdm7": cls.WDM7,
375
+ "thompson_aerosol": cls.AEROSOL_AWARE_THOMPSON,
376
+ "cesm_morrison": cls.MORRISON_WITH_CESM_AEROSOL,
377
+ "p311": cls.P3_1_ICE_1_MOMENT_QCLOUD,
378
+ "p312": cls.P3_1_ICE_2_MOMENT_QCLOUD,
379
+ "p322": cls.P3_2_ICE_2_MOMENT_QCLOUD,
380
+ "p3132": cls.P3_1_ICE_3_MOMENT_ICE_2_MOMENT_QCLOUD,
381
+ "jensen": cls.JENSEN_ISHMAEL,
382
+ "ntu": cls.NTU,
383
+ }
384
+
385
+ # check if key is in map
386
+ if key not in integer_label_map:
387
+ logger.error(
388
+ f"Key error: {key}. Valid key: {list(integer_label_map.keys())}"
389
+ )
390
+ raise KeyError
391
+
392
+ return integer_label_map[key]
393
+
394
+
395
+ __all__ = ["SchemeCumulus", "SchemeLandSurfaceModel", "SchemeLongWave", "SchemePBL", "SchemeShortWave", "SchemeSurfaceLayer", "SchemeMicrophysics"]
wrfrun/plot/wps.py CHANGED
@@ -12,29 +12,29 @@ from xarray import DataArray
12
12
  from wrfrun.utils import logger
13
13
 
14
14
  # Here defines the colormap for landuse and soiltype
15
- LANDUSE_CMAP = ListedColormap([
16
- [0, .4, 0], # 1 Evergreen Needleleaf Forest
17
- [0, .4, .2], # 2 Evergreen Broadleaf Forest
18
- [.2, .8, .2], # 3 Deciduous Needleleaf Forest
19
- [.2, .8, .4], # 4 Deciduous Broadleaf Forest
20
- [.2, .6, .2], # 5 Mixed Forests
21
- [.3, .7, 0], # 6 Closed Shrublands
22
- [.82, .41, .12], # 7 Open Shurblands
23
- [.74, .71, .41], # 8 Woody Savannas
24
- [1, .84, .0], # 9 Savannas
25
- [0, 1, 0], # 10 Grasslands
26
- [0, 1, 1], # 11 Permanant Wetlands
27
- [1, 1, 0], # 12 Croplands
28
- [1, 0, 0], # 13 Urban and Built-up
29
- [.7, .9, .3], # 14 Cropland/Natual Vegation Mosaic
30
- [1, 1, 1], # 15 Snow and Ice
31
- [.914, .914, .7], # 16 Barren or Sparsely Vegetated
32
- [.5, .7, 1], # 17 Water (like oceans)
33
- [.86, .08, .23], # 18 Wooded Tundra
34
- [.97, .5, .31], # 19 Mixed Tundra
35
- [.91, .59, .48], # 20 Barren Tundra
36
- [0, 0, .88], # 21 Lake
37
- ])
15
+ LANDUSE_CMAP = ListedColormap((
16
+ [0, .4, 0], # 1: Evergreen Needleleaf Forest
17
+ [0, .4, .2], # 2: Evergreen Broadleaf Forest
18
+ [.2, .8, .2], # 3: Deciduous Needleleaf Forest
19
+ [.2, .8, .4], # 4: Deciduous Broadleaf Forest
20
+ [.2, .6, .2], # 5: Mixed Forests
21
+ [.3, .7, 0], # 6: Closed Shrublands
22
+ [.82, .41, .12], # 7: Open Shurblands
23
+ [.74, .71, .41], # 8: Woody Savannas
24
+ [1, .84, .0], # 9: Savannas
25
+ [0, 1, 0], # 10: Grasslands
26
+ [0, 1, 1], # 11: Permanent Wetlands
27
+ [1, 1, 0], # 12: Croplands
28
+ [1, 0, 0], # 13: Urban and Built-up
29
+ [.7, .9, .3], # 14: Cropland/Natual Vegation Mosaic
30
+ [1, 1, 1], # 15: Snow and Ice
31
+ [.914, .914, .7], # 16: Barren or Sparsely Vegetated
32
+ [.5, .7, 1], # 17: Water (like oceans)
33
+ [.86, .08, .23], # 18: Wooded Tundra
34
+ [.97, .5, .31], # 19: Mixed Tundra
35
+ [.91, .59, .48], # 20: Barren Tundra
36
+ [0, 0, .88], # 21: Lake
37
+ ))
38
38
 
39
39
  LANDUSE_LABELS = [
40
40
  'Evergreen Needleleaf Forest',
@@ -61,25 +61,25 @@ LANDUSE_LABELS = [
61
61
  ]
62
62
 
63
63
 
64
- # Here defines the colormap and labels for soil type
65
- SOILTYPE_CMAP = ListedColormap([
66
- [0, .4, 0], # 1 Sand
67
- [0, .4, .2], # 2 Loamy Sand
68
- [.2, .8, .2], # 3 Sandy Loam
69
- [.2, .8, .4], # 4 Silt Loam
70
- [.2, .6, .2], # 5 Silt
71
- [.3, .7, 0], # 6 Loam
72
- [.82, .41, .12], # 7 Sandy Clay Loam
73
- [.74, .71, .41], # 8 Silty Clay Loam
74
- [1, .84, .0], # 9 Clay Loam
75
- [0, 1, 0], # 10 Sandy Clay
76
- [0, 1, 1], # 11 Silty Clay
77
- [1, 1, 0], # 12 Clay
78
- [1, 0, 0], # 13 Organic Material
79
- [.7, .9, .3], # 14 Water
80
- [1, 1, 1], # 15 Bedrock
81
- [.914, .914, .7] # 16 Other
82
- ])
64
+ # Here defines the colormap and labels for soil types
65
+ SOILTYPE_CMAP = ListedColormap((
66
+ [0, .4, 0], # 1: Sand
67
+ [0, .4, .2], # 2: Loamy Sand
68
+ [.2, .8, .2], # 3: Sandy Loam
69
+ [.2, .8, .4], # 4: Silt Loam
70
+ [.2, .6, .2], # 5: Silt
71
+ [.3, .7, 0], # 6: Loam
72
+ [.82, .41, .12], # 7: Sandy Clay Loam
73
+ [.74, .71, .41], # 8: Silty Clay Loam
74
+ [1, .84, .0], # 9: Clay Loam
75
+ [0, 1, 0], # 10: Sandy Clay
76
+ [0, 1, 1], # 11: Silty Clay
77
+ [1, 1, 0], # 12: Clay
78
+ [1, 0, 0], # 13: Organic Material
79
+ [.7, .9, .3], # 14: Water
80
+ [1, 1, 1], # 15: Bedrock
81
+ [.914, .914, .7] # 16: Other
82
+ ))
83
83
 
84
84
  SOILTYPE_LABELS = [
85
85
  "Sand",
@@ -102,13 +102,13 @@ SOILTYPE_LABELS = [
102
102
 
103
103
 
104
104
  def get_cmap_ticks(name: str) -> tuple:
105
- """Get corresponding colormap, labels and ticks.
106
-
107
- Args:
108
- name (str): Field name.
105
+ """
106
+ Get corresponding colormap, labels and ticks.
109
107
 
110
- Returns:
111
- tuple: (colormap, labels, ticks)
108
+ :param name: File name.
109
+ :type name: str
110
+ :return: (colormap, labels, ticks)
111
+ :rtype: tuple
112
112
  """
113
113
  # name map
114
114
  cmap_ticks_map = {
@@ -141,15 +141,23 @@ def get_cmap_ticks(name: str) -> tuple:
141
141
 
142
142
 
143
143
  def draw_geogrid(data_path: str, field: str, fig: Figure, nrow: int, ncol: int, index: int) -> Tuple[GeoAxes, QuadMesh]:
144
- """Draw specific data in geo_em*
145
-
146
- Args:
147
- data_path (str): data path.
148
- field (str): Which field you want to draw.
149
- fig (Figure): Matplotlib figure object.
150
- nrow (int): Row number of axes.
151
- ncol (int): Column number of axes.
152
- index (int): Index of axes.
144
+ """
145
+ Draw specific data in geogrid outputs.
146
+
147
+ :param data_path: Data path.
148
+ :type data_path: str
149
+ :param field: Which field you want to draw.
150
+ :type field: str
151
+ :param fig: Matplotlib figure object.
152
+ :type fig: Figure
153
+ :param nrow: Row number of axes.
154
+ :type nrow: int
155
+ :param ncol: Column number of axes.
156
+ :type ncol: int
157
+ :param index: Index of axes.
158
+ :type index: int
159
+ :return: (GeoAxes, QuadMesh)
160
+ :rtype: tuple
153
161
  """
154
162
  # take out data
155
163
  data: DataArray = getvar(Dataset(data_path), field) # type: ignore
@@ -159,7 +167,7 @@ def draw_geogrid(data_path: str, field: str, fig: Figure, nrow: int, ncol: int,
159
167
  data = data.argmax(dim="soil_cat", keep_attrs=True) # type: ignore
160
168
  # get data attrs
161
169
  data_attrs = data.attrs
162
- data = data + 1
170
+ data = data + 1 # type: ignore
163
171
  data.attrs = data_attrs
164
172
 
165
173
  # get latitude and longitude
@@ -109,7 +109,9 @@ dx = 9000
109
109
  dy = 9000
110
110
 
111
111
  # Projection.
112
- map_proj = { name = 'lambert', truelat1 = 34.0, truelat2 = 40.0}
112
+ map_proj = 'lambert'
113
+ truelat1 = 34.0
114
+ truelat2 = 40.0
113
115
 
114
116
  # Central point of the first area.
115
117
  ref_lat = 37.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wrfrun
3
- Version: 0.1.7
3
+ Version: 0.1.8
4
4
  Summary: wrfrun is a comprehensive toolkit for managing and using WRF
5
5
  Keywords: WRF
6
6
  Author-Email: Syize <syizeliu@gmail.com>
@@ -10,7 +10,7 @@ Project-URL: homepage, https://github.com/Syize/wrfrun
10
10
  Project-URL: repository, https://github.com/Syize/wrfrun
11
11
  Project-URL: documentation, https://wrfrun.syize.cn
12
12
  Project-URL: Bug Tracker, https://github.com/Syize/wrfrun/issues
13
- Requires-Python: <3.13
13
+ Requires-Python: >=3.10
14
14
  Requires-Dist: numpy<2.0.0
15
15
  Requires-Dist: xarray
16
16
  Requires-Dist: netCDF4
@@ -1,38 +1,43 @@
1
- wrfrun-0.1.7.dist-info/METADATA,sha256=nrPBmS0UxcjIiCN9wLyL798-r3OKpirBJUPlWrzobw8,2912
2
- wrfrun-0.1.7.dist-info/WHEEL,sha256=5J4neoE7k6LMgx4Fz1FHgBiO3YevhJGtNQ3muDrdLQM,75
1
+ wrfrun-0.1.8.dist-info/METADATA,sha256=_Y0huf7Q8hAsLFsgIlPZYF8FDmZ_DKqsGMxcBaewcpQ,2913
2
+ wrfrun-0.1.8.dist-info/WHEEL,sha256=5J4neoE7k6LMgx4Fz1FHgBiO3YevhJGtNQ3muDrdLQM,75
3
3
  wrfrun/__init__.py,sha256=l2zGk2qDWa3EXIlwvzqBYZHOU9273TN75Rmvx_7PAYM,58
4
- wrfrun/data.py,sha256=AjkDSZqkLROnWLw9qDOBUctoQmJ3R1bkfjnPzLMjPfs,14751
4
+ wrfrun/data.py,sha256=W6IhopHpp0lhvVo-beuO6NsbfsGDmN5MNf8Bqkt7xsA,14845
5
5
  wrfrun/pbs.py,sha256=gzRHbYqpU-c8lynu39TUKNvmPntvrPwfQVxK337yvjw,2454
6
6
  wrfrun/run.py,sha256=0mvuI98gLjq1gP1eaLUZiU1LJMCjtL668aKZTwu3n2g,9114
7
7
  wrfrun/utils.py,sha256=v3ZRu3Rd8-pZjo7I0PrJtgBN1zIBAt_nVPs0BP_DFwY,8118
8
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
9
+ wrfrun/core/__init__.py,sha256=zsitfcmbO_Qf_Uh0FzZ4rceZAo3WEYev32jSjgRjtkw,1325
10
+ wrfrun/core/base.py,sha256=zix413Nc0YrgIR6oakVhTN405KUmZ7OKlJTgL0fNUVc,30307
11
+ wrfrun/core/config.py,sha256=g021WEkRZpvsLyzVHlahL9WtAP7zKG9polW3B84eT3k,29252
12
+ wrfrun/core/error.py,sha256=etnImryyqDUggfZOKK1ynOm71GRSFJVGGOwhuiZahTI,2383
13
+ wrfrun/core/replay.py,sha256=nqVmR3Hb4zO6PnROssv3PKw7gvvdi-UqIsjX-NV1WLI,4782
14
+ wrfrun/core/server.py,sha256=RjzFVlRZg60rLMy4Gy5UhZWPUOQP307rT4ttpvbcecQ,8640
15
+ wrfrun/extension/__init__.py,sha256=YDYCS0KD3e-uLvf1K08ktNfP2sUSKpbgkHrvXj21EPQ,913
16
16
  wrfrun/extension/utils.py,sha256=OBIAlAXakbh1QhrF2BFlYAFV062ZfJjX0mYJkmcU_RI,2751
17
+ wrfrun/extension/goos_sst/__init__.py,sha256=M8LWGLXqHyPUWijl5925jFmwJ1ih3kHfT2jTxZzwMBA,2126
18
+ wrfrun/extension/goos_sst/core.py,sha256=D0po6PjBqcEareVQO1VjdIUrFz9lJrnAZ5q2sax78Tw,3794
19
+ wrfrun/extension/goos_sst/utils.py,sha256=h0OBCwxS67kG6YNclZLvyPYnT7uNZd3Uq9f6Vg2EaMc,3052
20
+ wrfrun/extension/goos_sst/res/__init__.py,sha256=M-qN-WI0EIvhYo2hwnnIK_fXL3TbR12KzSC9fvjgDaY,164
21
+ wrfrun/extension/goos_sst/res/Vtable.ERA_GOOS_SST,sha256=aX8RSTWL8GVdxf2TgvIoQx5xDVuLi0F5_Eg2e8Gaa-E,529
17
22
  wrfrun/extension/littler/__init__.py,sha256=pG-YPVG0gJIJ6s4xcAz9S_CnUxpUcz33wl9eNUSgxGk,20
18
23
  wrfrun/extension/littler/utils.py,sha256=TsN3GiAFszPWF7RNM_hYdARRY_OLL8mYm87UyZupUtU,21615
19
24
  wrfrun/model/__init__.py,sha256=lQNNnh3evXZytLAjdnhlIEFWerP1L0XAgDAUQhqIRyE,119
20
25
  wrfrun/model/base.py,sha256=WnVNu12ICJgThfZR7kK6_XLCQWVYFsHrdyAz8wl_YRc,218
21
- wrfrun/model/plot.py,sha256=ATG5nl5kV8YfoeNFIPLCUnnIQIrfIFNGPb9d8raM6S0,1582
26
+ wrfrun/model/plot.py,sha256=Hh-GxQPDzpwAEAq-rFh0VcIWzgMDxZVT0c40SIRa6_o,1582
22
27
  wrfrun/model/utils.py,sha256=Pyj9D9NMKw3wQcZcM7pJaLG09Vov447AxFKoVeZZU2s,1155
23
28
  wrfrun/model/wrf/__init__.py,sha256=T3S1BD9QDoW4uq871QW4_8-2BvCRWYEecz71EcdbMaI,136
24
- wrfrun/model/wrf/core.py,sha256=FEzRXUKK5dENxev3wR_GON5n1Zxq4Hj-Bs_BNP7P_ok,32134
29
+ wrfrun/model/wrf/core.py,sha256=srOD7KFF5TgPAcWTw0PLHFjkGjDzb8PYbxuPx5B4bQE,32140
25
30
  wrfrun/model/wrf/exec_wrap.py,sha256=gIsGZDAjzRzxt24eo8t-laIK4UBiyKf_ysfAZLlE1og,3918
26
31
  wrfrun/model/wrf/geodata.py,sha256=X9OUOm0__5NI7sl2z1F9_ur5wZ4P0HkpBNcRZQYKof0,9740
27
32
  wrfrun/model/wrf/_metgrid.py,sha256=i2qILM_1LkdnBZqXXL3swVhMRvhFvq4bOcRPGI6kSzg,2248
28
- wrfrun/model/wrf/namelist.py,sha256=t_JuWYj4oNNVwzTMKo6BNlv2LIq4t3JC7ZgVkaKfNbA,14923
33
+ wrfrun/model/wrf/namelist.py,sha256=T9b5H6pCljhKUhoR9qwTbdMF04Hrdp3mHwCP-VuhFWE,14791
29
34
  wrfrun/model/wrf/_ndown.py,sha256=ZcWttGXiT5FzGCAohmbeNU6bi8GUOUleiTK0ivn2BaI,1548
30
- wrfrun/model/wrf/scheme.py,sha256=F7HxoaNkkPpjkse5t9sGS3CJDvn_yBdHoaCG7WLdbqY,8524
35
+ wrfrun/model/wrf/scheme.py,sha256=8y85Dbu-GajwjHr3Spw8_tN21xAloD-SnmxJd11nXKE,11254
31
36
  wrfrun/model/wrf/vtable.py,sha256=0V4fo0Limnx4oJ2NByq_eHPzj8L4mnHNlrKL34Buw1A,2432
32
37
  wrfrun/plot/__init__.py,sha256=9Kn0IgkX10sHEqHJwk7mZV-dP14XMNcvXN8znO89FIw,19
33
- wrfrun/plot/wps.py,sha256=AQ1B6llNUrPU3PR8XKNLSzs_H-v60a0Wep-8Mcto6NM,5319
38
+ wrfrun/plot/wps.py,sha256=pvkxbh5760AAM4KaPteMzhFniZZFtkYF31xhzSBa7lo,5552
34
39
  wrfrun/res/__init__.py,sha256=YBcVaM2EZZJkDDvyKdk-WZmcFQoTFENZKCwcIQzEf3I,1133
35
- wrfrun/res/config.toml.template,sha256=aVXCSzhbV3P-MQCZOk2g-y0auRmqgr3jW920W3wks9g,4386
40
+ wrfrun/res/config.toml.template,sha256=LTCEwXSFF2QXnwGRoB0Jw5Qs_vXwdb6Zd7fQtNAz9Uw,4374
36
41
  wrfrun/res/run.sh.template,sha256=ZN7k0a9ONOtZUQ67JiTva-0DNVJG5O7BdOXQ8-LCscs,247
37
42
  wrfrun/res/extension/plotgrids.ncl,sha256=B0mvH1H1j_w7EEana9HmU1XJZtG0w9IccQ54zXpbQG0,7546
38
43
  wrfrun/res/namelist/namelist.input.da_wrfvar.template,sha256=Cwc-XPu_spJeQte4duWrulPBOLRMEBtn0mIn0pgMmKY,4912
@@ -43,4 +48,4 @@ wrfrun/res/namelist/namelist.wps.template,sha256=HlA7-SHs4C-cKRb3h6D0Kl1Y-5VSJ1L
43
48
  wrfrun/res/namelist/parame.in.template,sha256=vR8JSix20FAKGqj6jK8QuEAeWkGvg8_iptdVlzjPX6o,259
44
49
  wrfrun/res/job_scheduler/pbs.template,sha256=m7eyvZkzQRpjs43CvSeZ1biHYNyEJJkgXt3IU5ZhCmg,148
45
50
  wrfrun/res/job_scheduler/slurm.template,sha256=BrKL8DcHfpFfv0y0z7Qe_cqjwfzMyF-3V6vM72ehr9Y,312
46
- wrfrun-0.1.7.dist-info/RECORD,,
51
+ wrfrun-0.1.8.dist-info/RECORD,,
File without changes