wrfrun 0.1.9__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. wrfrun/__init__.py +8 -3
  2. wrfrun/cli.py +74 -31
  3. wrfrun/core/__init__.py +27 -10
  4. wrfrun/core/_config.py +308 -0
  5. wrfrun/core/_constant.py +236 -0
  6. wrfrun/core/_exec_db.py +105 -0
  7. wrfrun/core/_namelist.py +287 -0
  8. wrfrun/core/_record.py +178 -0
  9. wrfrun/core/_resource.py +172 -0
  10. wrfrun/core/base.py +136 -380
  11. wrfrun/core/core.py +196 -0
  12. wrfrun/core/error.py +35 -2
  13. wrfrun/core/replay.py +10 -96
  14. wrfrun/core/server.py +74 -32
  15. wrfrun/core/type.py +171 -0
  16. wrfrun/data.py +312 -149
  17. wrfrun/extension/goos_sst/__init__.py +2 -2
  18. wrfrun/extension/goos_sst/core.py +9 -14
  19. wrfrun/extension/goos_sst/res/__init__.py +0 -1
  20. wrfrun/extension/goos_sst/utils.py +50 -44
  21. wrfrun/extension/littler/core.py +105 -88
  22. wrfrun/extension/utils.py +5 -3
  23. wrfrun/log.py +117 -0
  24. wrfrun/model/__init__.py +11 -7
  25. wrfrun/model/constants.py +52 -0
  26. wrfrun/model/palm/__init__.py +30 -0
  27. wrfrun/model/palm/core.py +145 -0
  28. wrfrun/model/palm/namelist.py +33 -0
  29. wrfrun/model/plot.py +99 -114
  30. wrfrun/model/type.py +116 -0
  31. wrfrun/model/utils.py +9 -19
  32. wrfrun/model/wrf/__init__.py +4 -9
  33. wrfrun/model/wrf/core.py +262 -165
  34. wrfrun/model/wrf/exec_wrap.py +13 -12
  35. wrfrun/model/wrf/geodata.py +116 -99
  36. wrfrun/model/wrf/log.py +103 -0
  37. wrfrun/model/wrf/namelist.py +92 -76
  38. wrfrun/model/wrf/plot.py +102 -0
  39. wrfrun/model/wrf/scheme.py +108 -52
  40. wrfrun/model/wrf/utils.py +39 -24
  41. wrfrun/model/wrf/vtable.py +42 -7
  42. wrfrun/plot/__init__.py +20 -0
  43. wrfrun/plot/wps.py +90 -73
  44. wrfrun/res/__init__.py +115 -5
  45. wrfrun/res/config/config.template.toml +15 -0
  46. wrfrun/res/config/palm.template.toml +23 -0
  47. wrfrun/run.py +121 -77
  48. wrfrun/scheduler/__init__.py +1 -0
  49. wrfrun/scheduler/lsf.py +4 -1
  50. wrfrun/scheduler/pbs.py +4 -1
  51. wrfrun/scheduler/script.py +19 -5
  52. wrfrun/scheduler/slurm.py +4 -1
  53. wrfrun/scheduler/utils.py +14 -2
  54. wrfrun/utils.py +88 -199
  55. wrfrun/workspace/__init__.py +8 -5
  56. wrfrun/workspace/core.py +21 -11
  57. wrfrun/workspace/palm.py +137 -0
  58. wrfrun/workspace/wrf.py +59 -14
  59. wrfrun-0.3.0.dist-info/METADATA +240 -0
  60. wrfrun-0.3.0.dist-info/RECORD +78 -0
  61. wrfrun/core/config.py +0 -767
  62. wrfrun/model/base.py +0 -14
  63. wrfrun-0.1.9.dist-info/METADATA +0 -68
  64. wrfrun-0.1.9.dist-info/RECORD +0 -62
  65. {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/WHEEL +0 -0
  66. {wrfrun-0.1.9.dist-info → wrfrun-0.3.0.dist-info}/entry_points.txt +0 -0
@@ -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)
@@ -17,7 +17,6 @@ VTABLE_ERA_GOOS_SST
17
17
 
18
18
  from os.path import abspath, dirname
19
19
 
20
-
21
20
  _PATH = abspath(dirname(__file__))
22
21
 
23
22
  VTABLE_ERA_GOOS_SST = f"{_PATH}/Vtable.ERA_GOOS_SST"
@@ -6,22 +6,21 @@ Functions that are used by :doc:`/api/extension.goos_sst`.
6
6
 
7
7
  .. autosummary::
8
8
  :toctree: generated/
9
-
9
+
10
10
  create_sst_grib
11
11
  """
12
12
 
13
- from cfgrib.xarray_to_grib import to_grib
14
13
  from numpy.dtypes import DateTime64DType
15
14
  from pandas import to_datetime
16
15
  from xarray import DataArray, Dataset
17
16
 
18
- from wrfrun.utils import logger
17
+ from wrfrun.log import logger
19
18
 
20
19
 
21
20
  def create_sst_grib(data: DataArray, save_path: str):
22
21
  """
23
22
  Write SST data to a GRIB file.
24
-
23
+
25
24
  This function creates GRIB file using ``cfgrib`` package.
26
25
  While GRIB write support is experimental in ``cfgrib``,
27
26
  this function may **FAIL TO CREATE GRIB FILE**.
@@ -31,13 +30,16 @@ def create_sst_grib(data: DataArray, save_path: str):
31
30
  :param save_path: Output GRIB file path.
32
31
  :type save_path: str
33
32
  """
33
+ # lazy import to fix sphinx build error
34
+ from cfgrib.xarray_to_grib import to_grib
35
+
34
36
  # check the data's dimensions.
35
37
  for _dim in ["time", "longitude", "latitude"]:
36
38
  if _dim not in data.dims:
37
39
  logger.error(f"Essential dimension '{_dim}' not found in data")
38
40
  raise KeyError
39
41
 
40
- if not isinstance(data["time"].dtype, DateTime64DType): # type: ignore
42
+ if not isinstance(data["time"].dtype, DateTime64DType): # type: ignore
41
43
  data = data.assign_coords(time=to_datetime(data["time"].data))
42
44
 
43
45
  data = data.sortby(data["latitude"], ascending=False)
@@ -50,47 +52,51 @@ def create_sst_grib(data: DataArray, save_path: str):
50
52
  latitude_length = data["latitude"].size
51
53
  points_number = data.size
52
54
 
53
- data = data.assign_attrs(**{
54
- "units": "K",
55
- "long_name": "Sea surface temperature",
56
- "standard_name": "Sea surface temperature",
57
- # The following keys and values will be used in GRIB.
58
- "GRIB_paramId": 34,
59
- "GRIB_shortName": "sst",
60
- "GRIB_units": "K",
61
- "GRIB_name": "Sea surface temperature",
62
- "GRIB_stepUnits": 1,
63
- "GRIB_stepType": "instant",
64
- "GRIB_gridType": "regular_ll",
65
- "GRIB_iDirectionIncrementInDegrees": delta_longitude,
66
- "GRIB_iScanNegatively": 0,
67
- "GRIB_jDirectionIncrementInDegrees": delta_latitude,
68
- "GRIB_jScanPositively": 0,
69
- "GRIB_latitudeOfFirstGridPointInDegrees": latitude_start,
70
- "GRIB_latitudeOfLastGridPointInDegrees": latitude_stop,
71
- "GRIB_longitudeOfFirstGridPointInDegrees": longitude_start,
72
- "GRIB_longitudeOfLastGridPointInDegrees": longitude_stop,
73
- "GRIB_Ny": latitude_length,
74
- "GRIB_Nx": longitude_length,
75
- "GRIB_typeOfLevel": "surface",
76
- # The following keys and values can't be found at ECMWF websites.
77
- "GRIB_cfName": "unknown",
78
- "GRIB_cfVarName": "sst",
79
- "GRIB_dataType": "an", # Analysis data, defined at https://codes.ecmwf.int/grib/format/mars/type/
80
- "GRIB_gridDefinitionDescription": "Latitude/Longitude Grid",
81
- # "GRIB_missingValue": -9999,
82
- "GRIB_numberOfPoints": points_number,
83
- "GRIB_totalNumber": 0,
84
- "GRIB_uvRelativeToGird": 0
85
- })
55
+ data = data.assign_attrs(
56
+ **{
57
+ "units": "K",
58
+ "long_name": "Sea surface temperature",
59
+ "standard_name": "Sea surface temperature",
60
+ # The following keys and values will be used in GRIB.
61
+ "GRIB_paramId": 34,
62
+ "GRIB_shortName": "sst",
63
+ "GRIB_units": "K",
64
+ "GRIB_name": "Sea surface temperature",
65
+ "GRIB_stepUnits": 1,
66
+ "GRIB_stepType": "instant",
67
+ "GRIB_gridType": "regular_ll",
68
+ "GRIB_iDirectionIncrementInDegrees": delta_longitude,
69
+ "GRIB_iScanNegatively": 0,
70
+ "GRIB_jDirectionIncrementInDegrees": delta_latitude,
71
+ "GRIB_jScanPositively": 0,
72
+ "GRIB_latitudeOfFirstGridPointInDegrees": latitude_start,
73
+ "GRIB_latitudeOfLastGridPointInDegrees": latitude_stop,
74
+ "GRIB_longitudeOfFirstGridPointInDegrees": longitude_start,
75
+ "GRIB_longitudeOfLastGridPointInDegrees": longitude_stop,
76
+ "GRIB_Ny": latitude_length,
77
+ "GRIB_Nx": longitude_length,
78
+ "GRIB_typeOfLevel": "surface",
79
+ # The following keys and values can't be found at ECMWF websites.
80
+ "GRIB_cfName": "unknown",
81
+ "GRIB_cfVarName": "sst",
82
+ "GRIB_dataType": "an", # Analysis data, defined at https://codes.ecmwf.int/grib/format/mars/type/
83
+ "GRIB_gridDefinitionDescription": "Latitude/Longitude Grid",
84
+ # "GRIB_missingValue": -9999,
85
+ "GRIB_numberOfPoints": points_number,
86
+ "GRIB_totalNumber": 0,
87
+ "GRIB_uvRelativeToGird": 0,
88
+ }
89
+ )
86
90
 
87
91
  to_grib(
88
- Dataset({
89
- "sst": data
90
- }, attrs={
91
- "GRIB_centre": "ecmf",
92
- "GRIB_edition": 1,
93
- }), save_path
92
+ Dataset(
93
+ {"sst": data},
94
+ attrs={
95
+ "GRIB_centre": "ecmf",
96
+ "GRIB_edition": 1,
97
+ },
98
+ ),
99
+ save_path,
94
100
  )
95
101
 
96
102
 
@@ -13,15 +13,15 @@ Implementation of ``extension.littler``'s core functionality.
13
13
  LittleR
14
14
  """
15
15
 
16
- from json import loads, dumps
17
- from typing import Union, Tuple, Iterable
16
+ from json import dumps, loads
17
+ from typing import Iterable, Tuple, Union
18
18
  from zipfile import ZipFile
19
19
 
20
- from pandas import DataFrame, read_csv
21
20
  import numpy as np
21
+ from pandas import DataFrame, read_csv
22
22
 
23
- from wrfrun.core import WRFRUNConfig
24
- from wrfrun.utils import logger
23
+ from wrfrun.core import WRFRUN
24
+ from wrfrun.log import logger
25
25
 
26
26
 
27
27
  def to_fstring(var: Union[int, float, bool, str], length: Union[int, Tuple[int, int]]) -> str:
@@ -52,23 +52,15 @@ def to_fstring(var: Union[int, float, bool, str], length: Union[int, Tuple[int,
52
52
  """
53
53
  if isinstance(var, float):
54
54
  if not isinstance(length, tuple):
55
- logger.error(
56
- "`length` must be a tuple contain two values `(total length, decimal length)` when `var` is `float`"
57
- )
58
- raise ValueError(
59
- "`length` must be a tuple contain two values `(total length, decimal length)` when `var` is `float`"
60
- )
55
+ logger.error("`length` must be a tuple contain two values `(total length, decimal length)` when `var` is `float`")
56
+ raise ValueError("`length` must be a tuple contain two values `(total length, decimal length)` when `var` is `float`")
61
57
 
62
58
  res = f"{var:{length[0]}.{length[1]}f}"
63
59
 
64
60
  else:
65
61
  if not isinstance(length, int):
66
- logger.error(
67
- "`length` must be an int value when `var` is not `float`"
68
- )
69
- raise ValueError(
70
- "`length` must be an int value when `var` is not `float`"
71
- )
62
+ logger.error("`length` must be an int value when `var` is not `float`")
63
+ raise ValueError("`length` must be an int value when `var` is not `float`")
72
64
 
73
65
  if isinstance(var, bool):
74
66
  res = "T" if var else "F"
@@ -84,6 +76,7 @@ class LittleRHead(dict):
84
76
  """
85
77
  Headers of LITTLE_R observation data.
86
78
  """
79
+
87
80
  def __init__(
88
81
  self,
89
82
  longitude: float,
@@ -102,7 +95,7 @@ class LittleRHead(dict):
102
95
  cloud_cover=-888888,
103
96
  precipitable_water=-888888,
104
97
  quality_control: Union[dict, int] = 0,
105
- **kwargs
98
+ **kwargs,
106
99
  ) -> None:
107
100
  """
108
101
  Headers of LITTLE_R observation data.
@@ -125,7 +118,8 @@ class LittleRHead(dict):
125
118
  :type name: str
126
119
  :param source: Data source, defaults to "Created by wrfrun package".
127
120
  :type source: str
128
- :param num_sequence: Sequence number which is used to merge multiple record data, the less the num is, the newer the data is. Defaults to 0.
121
+ :param num_sequence: Sequence number which is used to merge multiple record data,
122
+ the less the num is, the newer the data is. Defaults to 0.
129
123
  :type num_sequence: int
130
124
  :param sea_level_pressure: Sea level pressure. Defaults to -888,888.
131
125
  :type sea_level_pressure: int
@@ -220,24 +214,26 @@ class LittleRHead(dict):
220
214
  # return self._convert_to_fstring()
221
215
 
222
216
  def _convert_to_fstring(self) -> str:
223
- return f"{self.latitude:20.5f}" \
224
- f"{self.longitude:20.5f}" \
225
- f"{self.ID.rjust(40, ' ')}" \
226
- f"{self.name.rjust(40, ' ')}" \
227
- f"{self.fm.rjust(40, ' ')}" \
228
- f"{self.source.rjust(40, ' ')}" \
229
- f"{self.elevation:20.5f}" \
230
- f"{self.num_valid_field:10d}" \
231
- f"{self.num_error:10d}" \
232
- f"{self.num_warning:10d}" \
233
- f"{self.num_sequence:10d}" \
234
- f"{self.num_duplicate:10d}" \
235
- f"{to_fstring(self.is_sounding, 10)}" \
236
- f"{to_fstring(self.is_bogus, 10)}" \
237
- f"{to_fstring(self.discard, 10)}" \
238
- f"{self.time:10d}" \
239
- f"{self.julian_day:10d}" \
240
- f"{self.date.rjust(20, ' ')}" + self._generate_data_qc()
217
+ return (
218
+ f"{self.latitude:20.5f}"
219
+ f"{self.longitude:20.5f}"
220
+ f"{self.ID.rjust(40, ' ')}"
221
+ f"{self.name.rjust(40, ' ')}"
222
+ f"{self.fm.rjust(40, ' ')}"
223
+ f"{self.source.rjust(40, ' ')}"
224
+ f"{self.elevation:20.5f}"
225
+ f"{self.num_valid_field:10d}"
226
+ f"{self.num_error:10d}"
227
+ f"{self.num_warning:10d}"
228
+ f"{self.num_sequence:10d}"
229
+ f"{self.num_duplicate:10d}"
230
+ f"{to_fstring(self.is_sounding, 10)}"
231
+ f"{to_fstring(self.is_bogus, 10)}"
232
+ f"{to_fstring(self.discard, 10)}"
233
+ f"{self.time:10d}"
234
+ f"{self.julian_day:10d}"
235
+ f"{self.date.rjust(20, ' ')}" + self._generate_data_qc()
236
+ )
241
237
 
242
238
  def _generate_data_qc(self) -> str:
243
239
  field = [
@@ -270,16 +266,26 @@ class LittleRHead(dict):
270
266
 
271
267
 
272
268
  LITTLE_R_DATA_FIELD = [
273
- "pressure", "pressure_qc",
274
- "height", "height_qc",
275
- "temperature", "temperature_qc",
276
- "dew_point", "dew_point_qc",
277
- "wind_speed", "wind_speed_qc",
278
- "wind_direction", "wind_direction_qc",
279
- "wind_u", "wind_u_qc",
280
- "wind_v", "wind_v_qc",
281
- "relative_humidity", "relative_humidity_qc",
282
- "thickness", "thickness_qc",
269
+ "pressure",
270
+ "pressure_qc",
271
+ "height",
272
+ "height_qc",
273
+ "temperature",
274
+ "temperature_qc",
275
+ "dew_point",
276
+ "dew_point_qc",
277
+ "wind_speed",
278
+ "wind_speed_qc",
279
+ "wind_direction",
280
+ "wind_direction_qc",
281
+ "wind_u",
282
+ "wind_u_qc",
283
+ "wind_v",
284
+ "wind_v_qc",
285
+ "relative_humidity",
286
+ "relative_humidity_qc",
287
+ "thickness",
288
+ "thickness_qc",
283
289
  ]
284
290
 
285
291
 
@@ -287,23 +293,24 @@ class LittleRData(DataFrame):
287
293
  """
288
294
  LITTLE_R observation data without headers.
289
295
  """
296
+
290
297
  def __init__(
291
298
  self,
292
299
  data=None,
293
300
  index=None,
294
301
  columns=None,
295
- pressure: Union[Iterable, float] = 100000.,
296
- height: Union[Iterable, float] = -888888.,
297
- temperature: Union[Iterable, float] = 264.,
298
- dew_point: Union[Iterable, float] = 263.,
299
- wind_speed: Union[Iterable, float] = -888888.,
300
- wind_direction: Union[Iterable, float] = -888888.,
301
- wind_u: Union[Iterable, float] = -888888.,
302
- wind_v: Union[Iterable, float] = -888888.,
303
- relative_humidity: Union[Iterable, float] = -888888.,
304
- thickness: Union[Iterable, float] = -888888.,
302
+ pressure: Union[Iterable, float] = 100000.0,
303
+ height: Union[Iterable, float] = -888888.0,
304
+ temperature: Union[Iterable, float] = 264.0,
305
+ dew_point: Union[Iterable, float] = 263.0,
306
+ wind_speed: Union[Iterable, float] = -888888.0,
307
+ wind_direction: Union[Iterable, float] = -888888.0,
308
+ wind_u: Union[Iterable, float] = -888888.0,
309
+ wind_v: Union[Iterable, float] = -888888.0,
310
+ relative_humidity: Union[Iterable, float] = -888888.0,
311
+ thickness: Union[Iterable, float] = -888888.0,
305
312
  quality_control_flag: Union[Iterable, dict, int] = 0,
306
- **kwargs
313
+ **kwargs,
307
314
  ) -> None:
308
315
  """
309
316
  LITTLE_R observation data without headers.
@@ -411,9 +418,7 @@ class LittleRData(DataFrame):
411
418
  wind_v = np.array([wind_v]).astype(float)
412
419
  relative_humidity = np.array([relative_humidity]).astype(float)
413
420
  thickness = np.array([thickness]).astype(float)
414
- quality_control_flag = np.array(
415
- [quality_control_flag]
416
- ).astype(int)
421
+ quality_control_flag = np.array([quality_control_flag]).astype(int)
417
422
  else:
418
423
  pressure = np.asarray(pressure).astype(float)
419
424
  height = np.asarray(height).astype(float)
@@ -425,9 +430,7 @@ class LittleRData(DataFrame):
425
430
  wind_v = np.asarray(wind_v).astype(float)
426
431
  relative_humidity = np.asarray(relative_humidity).astype(float)
427
432
  thickness = np.asarray(thickness).astype(float)
428
- quality_control_flag = np.asarray(
429
- quality_control_flag
430
- ).astype(int)
433
+ quality_control_flag = np.asarray(quality_control_flag).astype(int)
431
434
 
432
435
  # construct data
433
436
  if isinstance(quality_control_flag, dict):
@@ -493,7 +496,7 @@ class LittleRData(DataFrame):
493
496
  return cls.from_dict(data_dict)
494
497
 
495
498
  @classmethod
496
- def from_dict(cls, data: dict, orient='columns', dtype=None, columns=None):
499
+ def from_dict(cls, data: dict, orient="columns", dtype=None, columns=None):
497
500
  """
498
501
  Create ``LittleRData`` instance from a dict.
499
502
  This method inspects all fields in ``data`` and supplements any missing fields with invalid value (-888888).
@@ -517,7 +520,7 @@ class LittleRData(DataFrame):
517
520
  if field.endswith("_qc"):
518
521
  data[field] = np.zeros_like(temp_data).astype(int)
519
522
  else:
520
- data[field] = np.zeros_like(temp_data) - 888888.
523
+ data[field] = np.zeros_like(temp_data) - 888888.0
521
524
 
522
525
  return super().from_dict(data, orient, dtype, columns) # type: ignore
523
526
 
@@ -553,7 +556,7 @@ class LittleRData(DataFrame):
553
556
  res = ""
554
557
  valid_field_num = 0
555
558
  for row in self.index:
556
- for (key, qc_key) in zip(fields, qc_fields):
559
+ for key, qc_key in zip(fields, qc_fields):
557
560
  _field = self.loc[row, key]
558
561
  _field_qc = self.loc[row, qc_key]
559
562
 
@@ -564,7 +567,7 @@ class LittleRData(DataFrame):
564
567
  res += "\n"
565
568
 
566
569
  # add ending record
567
- for (_, _) in zip(fields, qc_fields):
570
+ for _, _ in zip(fields, qc_fields):
568
571
  res += f"{-777777:13.5f}{0:7d}"
569
572
  res += "\n"
570
573
 
@@ -587,18 +590,18 @@ class LittleR(LittleRData):
587
590
  index=None,
588
591
  columns=None,
589
592
  data_header: Union[dict, None] = None,
590
- pressure: Union[Iterable, float] = 100000.,
591
- height: Union[Iterable, float] = -888888.,
592
- temperature: Union[Iterable, float] = 264.,
593
- dew_point: Union[Iterable, float] = 263.,
594
- wind_speed: Union[Iterable, float] = -888888.,
595
- wind_direction: Union[Iterable, float] = -888888.,
596
- wind_u: Union[Iterable, float] = -888888.,
597
- wind_v: Union[Iterable, float] = -888888.,
598
- relative_humidity: Union[Iterable, float] = -888888.,
599
- thickness: Union[Iterable, float] = -888888.,
593
+ pressure: Union[Iterable, float] = 100000.0,
594
+ height: Union[Iterable, float] = -888888.0,
595
+ temperature: Union[Iterable, float] = 264.0,
596
+ dew_point: Union[Iterable, float] = 263.0,
597
+ wind_speed: Union[Iterable, float] = -888888.0,
598
+ wind_direction: Union[Iterable, float] = -888888.0,
599
+ wind_u: Union[Iterable, float] = -888888.0,
600
+ wind_v: Union[Iterable, float] = -888888.0,
601
+ relative_humidity: Union[Iterable, float] = -888888.0,
602
+ thickness: Union[Iterable, float] = -888888.0,
600
603
  quality_control_flag: Union[Iterable, dict, int] = 0,
601
- **kwargs
604
+ **kwargs,
602
605
  ) -> None:
603
606
  """
604
607
  ``LittleR`` class helps you manage LITTLE_R data easily.
@@ -751,7 +754,7 @@ class LittleR(LittleRData):
751
754
  quality_control_flag=quality_control_flag,
752
755
  index=index,
753
756
  columns=columns,
754
- **kwargs
757
+ **kwargs,
755
758
  )
756
759
 
757
760
  if data_header is None:
@@ -777,7 +780,7 @@ class LittleR(LittleRData):
777
780
  cloud_cover=-888888,
778
781
  precipitable_water=-888888,
779
782
  quality_control: Union[dict, int] = 0,
780
- **kwargs
783
+ **kwargs,
781
784
  ):
782
785
  """
783
786
  Set headers of LITTLE_R observation data.
@@ -801,7 +804,8 @@ class LittleR(LittleRData):
801
804
  :type name: str, optional
802
805
  :param source: Data source, defaults to "Created by wrfrun package".
803
806
  :type source: str, optional
804
- :param num_sequence: Sequence number, used to merge multiple record data, the less the num is, the newer the data is, defaults to 0
807
+ :param num_sequence: Sequence number, used to merge multiple record data,
808
+ the less the num is, the newer the data is, defaults to 0
805
809
  :type num_sequence: int, optional
806
810
  :param sea_level_pressure: Sea level pressure, defaults to -888888
807
811
  :type sea_level_pressure: int, optional
@@ -817,10 +821,23 @@ class LittleR(LittleRData):
817
821
  :type quality_control: Union[dict, int], optional
818
822
  """
819
823
  self.little_r_head = LittleRHead(
820
- longitude, latitude, fm, elevation, is_bogus, date, ID,
821
- name=name, source=source, num_sequence=num_sequence, sea_level_pressure=sea_level_pressure, reference_pressure=reference_pressure,
822
- surface_pressure=surface_pressure, cloud_cover=cloud_cover, precipitable_water=precipitable_water, quality_control=quality_control,
823
- **kwargs
824
+ longitude,
825
+ latitude,
826
+ fm,
827
+ elevation,
828
+ is_bogus,
829
+ date,
830
+ ID,
831
+ name=name,
832
+ source=source,
833
+ num_sequence=num_sequence,
834
+ sea_level_pressure=sea_level_pressure,
835
+ reference_pressure=reference_pressure,
836
+ surface_pressure=surface_pressure,
837
+ cloud_cover=cloud_cover,
838
+ precipitable_water=precipitable_water,
839
+ quality_control=quality_control,
840
+ **kwargs,
824
841
  )
825
842
 
826
843
  def __str__(self) -> str:
@@ -849,7 +866,7 @@ class LittleR(LittleRData):
849
866
  if not file_path.endswith(".zlr"):
850
867
  file_path = f"{file_path}.zlr"
851
868
 
852
- file_path = WRFRUNConfig.parse_resource_uri(file_path)
869
+ file_path = WRFRUN.config.parse_resource_uri(file_path)
853
870
 
854
871
  with ZipFile(file_path, "w") as zip_file:
855
872
  with zip_file.open("header", "w") as header_file:
@@ -868,7 +885,7 @@ class LittleR(LittleRData):
868
885
  :return: ``LittleR`` instance.
869
886
  :rtype: LittleR
870
887
  """
871
- file_path = WRFRUNConfig.parse_resource_uri(file_path)
888
+ file_path = WRFRUN.config.parse_resource_uri(file_path)
872
889
 
873
890
  with ZipFile(file_path, "r") as zip_file:
874
891
  with zip_file.open("header", "r") as header_file:
wrfrun/extension/utils.py CHANGED
@@ -15,15 +15,16 @@ from os.path import exists
15
15
  from shutil import copyfile
16
16
  from typing import List, Optional
17
17
 
18
- from wrfrun.core import WRFRUNConfig
19
- from wrfrun.utils import check_path, logger
18
+ from wrfrun.core import WRFRUN
19
+ from wrfrun.log import logger
20
+ from wrfrun.utils import check_path
20
21
 
21
22
 
22
23
  def extension_postprocess(output_dir: str, extension_id: str, outputs: Optional[List[str]] = None):
23
24
  """
24
25
  This function provides a unified postprocessing interface for all extensions.
25
26
 
26
- This function will save outputss and logs in ``output_dir`` to the ``{output_path}/extension_id`` and ``{output_path}/extension_id/logs``,
27
+ This function will save outputs and logs in ``output_dir`` to the ``{output_path}/extension_id`` and ``{output_path}/extension_id/logs``,
27
28
  in which ``output_path`` is defined in ``config.toml``.
28
29
  Files end with ``.log`` are treated as log files, while others are treated as outputs.
29
30
  You can save specific outputs by giving their names through the argument ``outputs``.
@@ -37,6 +38,7 @@ def extension_postprocess(output_dir: str, extension_id: str, outputs: Optional[
37
38
  :param outputs: A list contains multiple filenames. Files in this will be treated as outputs.
38
39
  :type outputs: list
39
40
  """
41
+ WRFRUNConfig = WRFRUN.config
40
42
  output_path = WRFRUNConfig.WRFRUN_OUTPUT_PATH
41
43
  output_save_path = f"{output_path}/{extension_id}"
42
44
  log_save_path = f"{output_path}/{extension_id}/logs"