wrfrun 0.1.8__py3-none-any.whl → 0.1.9__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/cli.py +128 -0
- wrfrun/core/base.py +8 -5
- wrfrun/core/config.py +81 -150
- wrfrun/core/replay.py +1 -1
- wrfrun/core/server.py +81 -78
- wrfrun/extension/goos_sst/__init__.py +5 -5
- wrfrun/extension/goos_sst/core.py +4 -1
- wrfrun/extension/goos_sst/res/Vtable.ERA_GOOS_SST +1 -1
- wrfrun/extension/goos_sst/res/__init__.py +17 -0
- wrfrun/extension/goos_sst/utils.py +21 -5
- wrfrun/extension/littler/__init__.py +57 -1
- wrfrun/extension/littler/{utils.py → core.py} +326 -40
- wrfrun/extension/utils.py +22 -21
- wrfrun/model/__init__.py +24 -1
- wrfrun/model/plot.py +253 -35
- wrfrun/model/utils.py +17 -8
- wrfrun/model/wrf/__init__.py +41 -0
- wrfrun/model/wrf/core.py +215 -99
- wrfrun/model/wrf/exec_wrap.py +49 -35
- wrfrun/model/wrf/namelist.py +79 -4
- wrfrun/model/wrf/{_metgrid.py → utils.py} +36 -2
- wrfrun/model/wrf/vtable.py +2 -1
- wrfrun/res/__init__.py +8 -5
- wrfrun/res/config/config.template.toml +50 -0
- wrfrun/res/{config.toml.template → config/wrf.template.toml} +7 -46
- wrfrun/res/run.template.sh +10 -0
- wrfrun/res/scheduler/lsf.template +5 -0
- wrfrun/res/{job_scheduler → scheduler}/pbs.template +1 -1
- wrfrun/res/{job_scheduler → scheduler}/slurm.template +2 -1
- wrfrun/run.py +19 -23
- wrfrun/scheduler/__init__.py +35 -0
- wrfrun/scheduler/env.py +44 -0
- wrfrun/scheduler/lsf.py +47 -0
- wrfrun/scheduler/pbs.py +48 -0
- wrfrun/scheduler/script.py +70 -0
- wrfrun/scheduler/slurm.py +48 -0
- wrfrun/scheduler/utils.py +14 -0
- wrfrun/utils.py +8 -3
- wrfrun/workspace/__init__.py +38 -0
- wrfrun/workspace/core.py +92 -0
- wrfrun/workspace/wrf.py +121 -0
- {wrfrun-0.1.8.dist-info → wrfrun-0.1.9.dist-info}/METADATA +3 -2
- wrfrun-0.1.9.dist-info/RECORD +62 -0
- wrfrun-0.1.9.dist-info/entry_points.txt +3 -0
- wrfrun/model/wrf/_ndown.py +0 -39
- wrfrun/pbs.py +0 -86
- wrfrun/res/run.sh.template +0 -16
- wrfrun/workspace.py +0 -88
- wrfrun-0.1.8.dist-info/RECORD +0 -51
- {wrfrun-0.1.8.dist-info → wrfrun-0.1.9.dist-info}/WHEEL +0 -0
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.extension.littler.core
|
|
3
|
+
#############################
|
|
4
|
+
|
|
5
|
+
Implementation of ``extension.littler``'s core functionality.
|
|
6
|
+
|
|
7
|
+
.. autosummary::
|
|
8
|
+
:toctree: generated/
|
|
9
|
+
|
|
10
|
+
to_fstring
|
|
11
|
+
LittleRHead
|
|
12
|
+
LittleRData
|
|
13
|
+
LittleR
|
|
14
|
+
"""
|
|
15
|
+
|
|
1
16
|
from json import loads, dumps
|
|
2
|
-
from typing import Union, Tuple
|
|
17
|
+
from typing import Union, Tuple, Iterable
|
|
3
18
|
from zipfile import ZipFile
|
|
4
19
|
|
|
5
20
|
from pandas import DataFrame, read_csv
|
|
@@ -13,9 +28,24 @@ def to_fstring(var: Union[int, float, bool, str], length: Union[int, Tuple[int,
|
|
|
13
28
|
"""
|
|
14
29
|
Convert a basic variable to a string following the Fortran standard.
|
|
15
30
|
|
|
31
|
+
Convert a float number to a string of length 7 with 3 decimal places:
|
|
32
|
+
|
|
33
|
+
>>> to_fstring(0.1, (7, 3))
|
|
34
|
+
' 0.100'
|
|
35
|
+
|
|
36
|
+
Convert an integer to a string of length 3:
|
|
37
|
+
|
|
38
|
+
>>> to_fstring(1, 3)
|
|
39
|
+
' 1'
|
|
40
|
+
|
|
41
|
+
Convert a boolean value to a string of length 4:
|
|
42
|
+
>>> to_fstring(True, 4)
|
|
43
|
+
' T'
|
|
44
|
+
|
|
16
45
|
:param var: Basic variable that can be one of the ``[int, float, bool, str]``.
|
|
17
46
|
:type var: Union[int, float, bool, str]
|
|
18
|
-
:param length: The length of the output string. If the type of ``var`` is ``float``,
|
|
47
|
+
:param length: The length of the output string. If the type of ``var`` is ``float``,
|
|
48
|
+
the length must contain two parameters ``(total length, decimal length)``.
|
|
19
49
|
:type length: Union[int, Tuple[int, int]]
|
|
20
50
|
:return: Converted string.
|
|
21
51
|
:rtype: str
|
|
@@ -29,7 +59,7 @@ def to_fstring(var: Union[int, float, bool, str], length: Union[int, Tuple[int,
|
|
|
29
59
|
"`length` must be a tuple contain two values `(total length, decimal length)` when `var` is `float`"
|
|
30
60
|
)
|
|
31
61
|
|
|
32
|
-
res = f"{var:{length[0]}.{length[1]}}"
|
|
62
|
+
res = f"{var:{length[0]}.{length[1]}f}"
|
|
33
63
|
|
|
34
64
|
else:
|
|
35
65
|
if not isinstance(length, int):
|
|
@@ -52,7 +82,7 @@ def to_fstring(var: Union[int, float, bool, str], length: Union[int, Tuple[int,
|
|
|
52
82
|
|
|
53
83
|
class LittleRHead(dict):
|
|
54
84
|
"""
|
|
55
|
-
|
|
85
|
+
Headers of LITTLE_R observation data.
|
|
56
86
|
"""
|
|
57
87
|
def __init__(
|
|
58
88
|
self,
|
|
@@ -74,13 +104,14 @@ class LittleRHead(dict):
|
|
|
74
104
|
quality_control: Union[dict, int] = 0,
|
|
75
105
|
**kwargs
|
|
76
106
|
) -> None:
|
|
77
|
-
"""
|
|
107
|
+
"""
|
|
108
|
+
Headers of LITTLE_R observation data.
|
|
78
109
|
|
|
79
110
|
:param longitude: Longitude.
|
|
80
111
|
:type longitude: float
|
|
81
112
|
:param latitude: Latitude.
|
|
82
113
|
:type latitude: float
|
|
83
|
-
:param fm: Platform code (FM-Code).
|
|
114
|
+
:param fm: Platform code (FM-Code). Here is the list of `Valid FM Codes <https://www2.mmm.ucar.edu/wrf/users/wrfda/OnlineTutorial/Help/littler.html#FM>`_.
|
|
84
115
|
:type fm: str
|
|
85
116
|
:param elevation: Elevation.
|
|
86
117
|
:type elevation: float
|
|
@@ -253,24 +284,117 @@ LITTLE_R_DATA_FIELD = [
|
|
|
253
284
|
|
|
254
285
|
|
|
255
286
|
class LittleRData(DataFrame):
|
|
287
|
+
"""
|
|
288
|
+
LITTLE_R observation data without headers.
|
|
289
|
+
"""
|
|
256
290
|
def __init__(
|
|
257
291
|
self,
|
|
258
292
|
data=None,
|
|
259
293
|
index=None,
|
|
260
294
|
columns=None,
|
|
261
|
-
pressure: Union[
|
|
262
|
-
height: Union[
|
|
263
|
-
temperature: Union[
|
|
264
|
-
dew_point: Union[
|
|
265
|
-
wind_speed: Union[
|
|
266
|
-
wind_direction: Union[
|
|
267
|
-
wind_u: Union[
|
|
268
|
-
wind_v: Union[
|
|
269
|
-
relative_humidity: Union[
|
|
270
|
-
thickness: Union[
|
|
271
|
-
quality_control_flag: Union[
|
|
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.,
|
|
305
|
+
quality_control_flag: Union[Iterable, dict, int] = 0,
|
|
272
306
|
**kwargs
|
|
273
307
|
) -> None:
|
|
308
|
+
"""
|
|
309
|
+
LITTLE_R observation data without headers.
|
|
310
|
+
|
|
311
|
+
:class:`LittleRData` inherits from ``pandas.DataFrame``, so you have two ways to create a ``LittleRData`` instance:
|
|
312
|
+
|
|
313
|
+
1. Create instance like normal ``pandas.DataFrame`` instance:
|
|
314
|
+
|
|
315
|
+
>>> obs_data = {
|
|
316
|
+
... "pressure": [100000., 90000.],
|
|
317
|
+
... "pressure_qc": [0, 0],
|
|
318
|
+
... "height": [-888888., -888888.],
|
|
319
|
+
... "height_qc": [0, 0],
|
|
320
|
+
... "temperature": [264., 260.],
|
|
321
|
+
... "temperature_qc": [0, 0],
|
|
322
|
+
... "dew_point": [263., 255.],
|
|
323
|
+
... "dew_point_qc": [0, 0],
|
|
324
|
+
... "wind_speed": [-888888., -888888.],
|
|
325
|
+
... "wind_speed_qc": [0, 0],
|
|
326
|
+
... "wind_direction": [-888888., -888888.],
|
|
327
|
+
... "wind_direction_qc": [0, 0],
|
|
328
|
+
... "wind_u": [-888888., -888888.],
|
|
329
|
+
... "wind_u_qc": [0, 0],
|
|
330
|
+
... "wind_v": [-888888., -888888.],
|
|
331
|
+
... "wind_v_qc": [0, 0],
|
|
332
|
+
... "relative_humidity": [-888888., -888888.],
|
|
333
|
+
... "relative_humidity_qc": [0, 0],
|
|
334
|
+
... "thickness": [-888888., -888888.],
|
|
335
|
+
... "thickness_qc": [0, 0],
|
|
336
|
+
... }
|
|
337
|
+
>>> littler_data = LittleRData(data=data)
|
|
338
|
+
|
|
339
|
+
However, you need to give all quality control flags, and make sure the ``data`` has all essential valus.
|
|
340
|
+
|
|
341
|
+
2. Create instance by giving each value one after another
|
|
342
|
+
|
|
343
|
+
>>> obs_data = LittleRData(
|
|
344
|
+
... pressure=[100000., 90000.],
|
|
345
|
+
... height=[-888888., -888888.],
|
|
346
|
+
... temperature=[264., 260.],
|
|
347
|
+
... dew_point=[263., 255.],
|
|
348
|
+
... wind_speed=[-888888., -888888.],
|
|
349
|
+
... wind_direction=[-888888., -888888.],
|
|
350
|
+
... wind_u=[-888888., -888888.],
|
|
351
|
+
... wind_v=[-888888., -888888.],
|
|
352
|
+
... relative_humidity=[-888888., -888888.],
|
|
353
|
+
... thickness=[-888888., -888888.],
|
|
354
|
+
... quality_control_flag=[0, 0],
|
|
355
|
+
... )
|
|
356
|
+
|
|
357
|
+
In this way, you can set all quality control flag of one pressure level by giving ``quality_control_flag``.
|
|
358
|
+
|
|
359
|
+
If you want to set an invalid value, **USE -888888**.
|
|
360
|
+
|
|
361
|
+
To generate a LITTLE_R format record, just use :func:`str`
|
|
362
|
+
|
|
363
|
+
>>> str(obs_data)
|
|
364
|
+
|
|
365
|
+
:param data: This argument is passed to ``pandas.DataFrame`` directly.
|
|
366
|
+
:type data: ndarray | Iterable | dict | DataFrame
|
|
367
|
+
:param index: This argument is passed to ``pandas.DataFrame`` directly.
|
|
368
|
+
:type index: Index or array-like
|
|
369
|
+
:param columns: This argument is passed to ``pandas.DataFrame`` directly.
|
|
370
|
+
:type columns: Index or array-like
|
|
371
|
+
:param pressure: Pressure in ``Pa``. Default is 100000 Pa.
|
|
372
|
+
:type pressure: float | Iterable
|
|
373
|
+
:param height: Elevation in ``meter``. Default is -888888.
|
|
374
|
+
:type height: float | Iterable
|
|
375
|
+
:param temperature: Air temperature in ``K``. Default is 264 K.
|
|
376
|
+
:type temperature: float | Iterable
|
|
377
|
+
:param dew_point: Dew point temperature in ``K``. Default is 263 K.
|
|
378
|
+
:type dew_point: float | Iterable
|
|
379
|
+
:param wind_speed: Wind speed in ``meter / seconds``. Default is -888888.
|
|
380
|
+
:type wind_speed: float | Iterable
|
|
381
|
+
:param wind_direction: Wind direction in ``degree``, 0/360 represents the north. Default is -888888.
|
|
382
|
+
:type wind_direction: float | Iterable
|
|
383
|
+
:param wind_u: East-west wind speed in ``meter / seconds``. Default is -888888.
|
|
384
|
+
:type wind_u: float | Iterable
|
|
385
|
+
:param wind_v: North-south wind speed in ``meter / seconds``. Default is -888888.
|
|
386
|
+
:type wind_v: float | Iterable
|
|
387
|
+
:param relative_humidity: Relative humidity in ``percentage``. Default is -888888.
|
|
388
|
+
:type relative_humidity: float | Iterable
|
|
389
|
+
:param thickness: Thickness in ``meter``. Default is -888888.
|
|
390
|
+
:type thickness: float | Iterable
|
|
391
|
+
:param quality_control_flag: Quality control flag for all data or data in the same line.
|
|
392
|
+
This argument can only be ``0``, ``1`` or array-like object which only contains 0 or 1.
|
|
393
|
+
``0`` means no quality control, ``1`` means having quality control. Default is 0.
|
|
394
|
+
:type quality_control_flag: int | Iterable
|
|
395
|
+
:param kwargs: Other keyword arguments passed to parent class.
|
|
396
|
+
:type kwargs: dict
|
|
397
|
+
"""
|
|
274
398
|
# check data type
|
|
275
399
|
if data is not None:
|
|
276
400
|
super().__init__(data=data, index=index, columns=columns, **kwargs) # type: ignore
|
|
@@ -356,20 +480,35 @@ class LittleRData(DataFrame):
|
|
|
356
480
|
super().__init__(data=data) # type: ignore
|
|
357
481
|
|
|
358
482
|
@classmethod
|
|
359
|
-
def from_csv(cls, csv_path):
|
|
483
|
+
def from_csv(cls, csv_path: str):
|
|
360
484
|
"""
|
|
361
|
-
Read saved
|
|
485
|
+
Read saved LITTLE_R data from a CSV file.
|
|
362
486
|
|
|
363
487
|
:param csv_path: CSV file path.
|
|
364
488
|
:type csv_path: str
|
|
365
|
-
:return:
|
|
366
|
-
:rtype:
|
|
489
|
+
:return: ``LittleRData`` instance.
|
|
490
|
+
:rtype: LittleRData
|
|
367
491
|
"""
|
|
368
492
|
data_dict = read_csv(csv_path).to_dict()
|
|
369
493
|
return cls.from_dict(data_dict)
|
|
370
494
|
|
|
371
495
|
@classmethod
|
|
372
496
|
def from_dict(cls, data: dict, orient='columns', dtype=None, columns=None):
|
|
497
|
+
"""
|
|
498
|
+
Create ``LittleRData`` instance from a dict.
|
|
499
|
+
This method inspects all fields in ``data`` and supplements any missing fields with invalid value (-888888).
|
|
500
|
+
|
|
501
|
+
:param data: A dict contains all data.
|
|
502
|
+
:type data: dict
|
|
503
|
+
:param orient: This argument is passed to ``DataFrame.from_dict`` directly.
|
|
504
|
+
:type orient: str
|
|
505
|
+
:param dtype: This argument is passed to ``DataFrame.from_dict`` directly.
|
|
506
|
+
:type dtype: dtype
|
|
507
|
+
:param columns: This argument is passed to ``DataFrame.from_dict`` directly.
|
|
508
|
+
:type columns: Index or array-like
|
|
509
|
+
:return: ``LittleRData`` instance.
|
|
510
|
+
:rtype: LittleRData
|
|
511
|
+
"""
|
|
373
512
|
# check fields
|
|
374
513
|
data_key = next(iter(data))
|
|
375
514
|
temp_data = data[data_key]
|
|
@@ -436,6 +575,9 @@ class LittleRData(DataFrame):
|
|
|
436
575
|
|
|
437
576
|
|
|
438
577
|
class LittleR(LittleRData):
|
|
578
|
+
"""
|
|
579
|
+
Manage LITTLE_R observation data.
|
|
580
|
+
"""
|
|
439
581
|
|
|
440
582
|
_metadata = ["little_r_head"]
|
|
441
583
|
|
|
@@ -445,19 +587,155 @@ class LittleR(LittleRData):
|
|
|
445
587
|
index=None,
|
|
446
588
|
columns=None,
|
|
447
589
|
data_header: Union[dict, None] = None,
|
|
448
|
-
pressure: Union[
|
|
449
|
-
height: Union[
|
|
450
|
-
temperature: Union[
|
|
451
|
-
dew_point: Union[
|
|
452
|
-
wind_speed: Union[
|
|
453
|
-
wind_direction: Union[
|
|
454
|
-
wind_u: Union[
|
|
455
|
-
wind_v: Union[
|
|
456
|
-
relative_humidity: Union[
|
|
457
|
-
thickness: Union[
|
|
458
|
-
quality_control_flag: Union[
|
|
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.,
|
|
600
|
+
quality_control_flag: Union[Iterable, dict, int] = 0,
|
|
459
601
|
**kwargs
|
|
460
602
|
) -> None:
|
|
603
|
+
"""
|
|
604
|
+
``LittleR`` class helps you manage LITTLE_R data easily.
|
|
605
|
+
You can create a ``LittleR`` instance with your observation data,
|
|
606
|
+
then generate LITTLE_R format record or save all data to a **Zipped Little R** file (ends with ``.zlr``).
|
|
607
|
+
|
|
608
|
+
**Zipped Little R** file is a compressed file having two parts: ``header`` and ``data``.
|
|
609
|
+
``header`` is a JSON file that stores LITTLE_R file header,
|
|
610
|
+
and ``data`` is a CSV file that stores record data.
|
|
611
|
+
You can even create ``.zlr`` file with other programs and read the file using ``LittleR``,
|
|
612
|
+
as long as it has all essential data.
|
|
613
|
+
|
|
614
|
+
1. Constructing LittleR from a dictionary
|
|
615
|
+
|
|
616
|
+
>>> obs_data = {
|
|
617
|
+
... "pressure": [100000., 90000.],
|
|
618
|
+
... "pressure_qc": [0, 0],
|
|
619
|
+
... "height": [-888888., -888888.],
|
|
620
|
+
... "height_qc": [0, 0],
|
|
621
|
+
... "temperature": [264., 260.],
|
|
622
|
+
... "temperature_qc": [0, 0],
|
|
623
|
+
... "dew_point": [263., 255.],
|
|
624
|
+
... "dew_point_qc": [0, 0],
|
|
625
|
+
... "wind_speed": [-888888., -888888.],
|
|
626
|
+
... "wind_speed_qc": [0, 0],
|
|
627
|
+
... "wind_direction": [-888888., -888888.],
|
|
628
|
+
... "wind_direction_qc": [0, 0],
|
|
629
|
+
... "wind_u": [-888888., -888888.],
|
|
630
|
+
... "wind_u_qc": [0, 0],
|
|
631
|
+
... "wind_v": [-888888., -888888.],
|
|
632
|
+
... "wind_v_qc": [0, 0],
|
|
633
|
+
... "relative_humidity": [-888888., -888888.],
|
|
634
|
+
... "relative_humidity_qc": [0, 0],
|
|
635
|
+
... "thickness": [-888888., -888888.],
|
|
636
|
+
... "thickness_qc": [0, 0],
|
|
637
|
+
... }
|
|
638
|
+
>>> obs_header = {
|
|
639
|
+
... "longitude": 120,
|
|
640
|
+
... "latitude": 60,
|
|
641
|
+
... "fm": "FM-19",
|
|
642
|
+
... "elevation": 0,
|
|
643
|
+
... "is_bogus": True,
|
|
644
|
+
... "date": "20250902070000"
|
|
645
|
+
...}
|
|
646
|
+
>>> littler_data = LittleR(data=data, data_header=obs_header)
|
|
647
|
+
|
|
648
|
+
You can set header after constructing LittleR
|
|
649
|
+
|
|
650
|
+
>>> obs_data = {
|
|
651
|
+
... "pressure": [100000., 90000.],
|
|
652
|
+
... "pressure_qc": [0, 0],
|
|
653
|
+
... "height": [-888888., -888888.],
|
|
654
|
+
... "height_qc": [0, 0],
|
|
655
|
+
... "temperature": [264., 260.],
|
|
656
|
+
... "temperature_qc": [0, 0],
|
|
657
|
+
... "dew_point": [263., 255.],
|
|
658
|
+
... "dew_point_qc": [0, 0],
|
|
659
|
+
... "wind_speed": [-888888., -888888.],
|
|
660
|
+
... "wind_speed_qc": [0, 0],
|
|
661
|
+
... "wind_direction": [-888888., -888888.],
|
|
662
|
+
... "wind_direction_qc": [0, 0],
|
|
663
|
+
... "wind_u": [-888888., -888888.],
|
|
664
|
+
... "wind_u_qc": [0, 0],
|
|
665
|
+
... "wind_v": [-888888., -888888.],
|
|
666
|
+
... "wind_v_qc": [0, 0],
|
|
667
|
+
... "relative_humidity": [-888888., -888888.],
|
|
668
|
+
... "relative_humidity_qc": [0, 0],
|
|
669
|
+
... "thickness": [-888888., -888888.],
|
|
670
|
+
... "thickness_qc": [0, 0],
|
|
671
|
+
... }
|
|
672
|
+
>>> littler_data = LittleR(data=data)
|
|
673
|
+
>>> littler_data.set_header(longitude=120, latitude=60, fm="FM-19", elevation=0, is_bogus=True, date="20250902070000")
|
|
674
|
+
|
|
675
|
+
2. Constructing LittleR by giving observation data one by one
|
|
676
|
+
|
|
677
|
+
>>> littler_data = LittleR(
|
|
678
|
+
... pressure=[100000., 90000.],
|
|
679
|
+
... height=[-888888., -888888.],
|
|
680
|
+
... temperature=[264., 260.],
|
|
681
|
+
... dew_point=[263., 255.],
|
|
682
|
+
... wind_speed=[-888888., -888888.],
|
|
683
|
+
... wind_direction=[-888888., -888888.],
|
|
684
|
+
... wind_u=[-888888., -888888.],
|
|
685
|
+
... wind_v=[-888888., -888888.],
|
|
686
|
+
... relative_humidity=[-888888., -888888.],
|
|
687
|
+
... thickness=[-888888., -888888.],
|
|
688
|
+
... quality_control_flag=[0, 0],
|
|
689
|
+
...)
|
|
690
|
+
|
|
691
|
+
3. Constructing LittleR by reading ``.zlr`` file
|
|
692
|
+
|
|
693
|
+
>>> zlr_file_path = "data/test.zlr"
|
|
694
|
+
>>> littler_data = LittleR.from_zlr(zlr_file_path)
|
|
695
|
+
|
|
696
|
+
4. Generating LITTLE_R format record
|
|
697
|
+
|
|
698
|
+
>>> str(littler_data)
|
|
699
|
+
|
|
700
|
+
5. Saving data to ``.zlr`` file
|
|
701
|
+
|
|
702
|
+
>>> littler_data.to_zlr("data/test.zlr")
|
|
703
|
+
|
|
704
|
+
:param data: This argument is passed to ``pandas.DataFrame`` directly.
|
|
705
|
+
:type data: ndarray | Iterable | dict | DataFrame
|
|
706
|
+
:param index: This argument is passed to ``pandas.DataFrame`` directly.
|
|
707
|
+
:type index: Index or array-like
|
|
708
|
+
:param columns: This argument is passed to ``pandas.DataFrame`` directly.
|
|
709
|
+
:type columns: Index or array-like
|
|
710
|
+
:param data_header: A dict contains LITTLE_R headers.
|
|
711
|
+
:type data_header: dict
|
|
712
|
+
:param pressure: Pressure in ``Pa``. Default is 100000 Pa.
|
|
713
|
+
:type pressure: float | Iterable
|
|
714
|
+
:param height: Elevation in ``meter``. Default is -888888.
|
|
715
|
+
:type height: float | Iterable
|
|
716
|
+
:param temperature: Air temperature in ``K``. Default is 264 K.
|
|
717
|
+
:type temperature: float | Iterable
|
|
718
|
+
:param dew_point: Dew point temperature in ``K``. Default is 263 K.
|
|
719
|
+
:type dew_point: float | Iterable
|
|
720
|
+
:param wind_speed: Wind speed in ``meter / seconds``. Default is -888888.
|
|
721
|
+
:type wind_speed: float | Iterable
|
|
722
|
+
:param wind_direction: Wind direction in ``degree``, 0/360 represents the north. Default is -888888.
|
|
723
|
+
:type wind_direction: float | Iterable
|
|
724
|
+
:param wind_u: East-west wind speed in ``meter / seconds``. Default is -888888.
|
|
725
|
+
:type wind_u: float | Iterable
|
|
726
|
+
:param wind_v: North-south wind speed in ``meter / seconds``. Default is -888888.
|
|
727
|
+
:type wind_v: float | Iterable
|
|
728
|
+
:param relative_humidity: Relative humidity in ``percentage``. Default is -888888.
|
|
729
|
+
:type relative_humidity: float | Iterable
|
|
730
|
+
:param thickness: Thickness in ``meter``. Default is -888888.
|
|
731
|
+
:type thickness: float | Iterable
|
|
732
|
+
:param quality_control_flag: Quality control flag for all data or data in the same line.
|
|
733
|
+
This argument can only be ``0``, ``1`` or array-like object which only contains 0 or 1.
|
|
734
|
+
``0`` means no quality control, ``1`` means having quality control. Default is 0.
|
|
735
|
+
:type quality_control_flag: int | Iterable
|
|
736
|
+
:param kwargs: Other keyword arguments passed to parent class.
|
|
737
|
+
:type kwargs: dict
|
|
738
|
+
"""
|
|
461
739
|
super().__init__(
|
|
462
740
|
data=data,
|
|
463
741
|
pressure=pressure,
|
|
@@ -501,13 +779,15 @@ class LittleR(LittleRData):
|
|
|
501
779
|
quality_control: Union[dict, int] = 0,
|
|
502
780
|
**kwargs
|
|
503
781
|
):
|
|
504
|
-
"""
|
|
782
|
+
"""
|
|
783
|
+
Set headers of LITTLE_R observation data.
|
|
505
784
|
|
|
506
785
|
:param longitude: Longitude.
|
|
507
786
|
:type longitude: float
|
|
508
787
|
:param latitude: Latitude.
|
|
509
788
|
:type latitude: float
|
|
510
789
|
:param fm: Platform code (FM-Code).
|
|
790
|
+
Here is the list of `Valid FM Codes <https://www2.mmm.ucar.edu/wrf/users/wrfda/OnlineTutorial/Help/littler.html#FM>`_.
|
|
511
791
|
:type fm: str
|
|
512
792
|
:param elevation: Elevation.
|
|
513
793
|
:type elevation: float
|
|
@@ -548,17 +828,23 @@ class LittleR(LittleRData):
|
|
|
548
828
|
return f"{str(self.little_r_head)}\n{data_str}"
|
|
549
829
|
|
|
550
830
|
@classmethod
|
|
551
|
-
def from_csv(cls, csv_path):
|
|
831
|
+
def from_csv(cls, csv_path: str):
|
|
832
|
+
"""
|
|
833
|
+
Read observation data from CSV file.
|
|
834
|
+
|
|
835
|
+
:param csv_path: CSV file path.
|
|
836
|
+
:type csv_path: str
|
|
837
|
+
:return: ``LittleR`` instance.
|
|
838
|
+
:rtype: LittleR
|
|
839
|
+
"""
|
|
552
840
|
return super().from_csv(csv_path)
|
|
553
841
|
|
|
554
842
|
def to_zlr(self, file_path: str):
|
|
555
843
|
"""
|
|
556
|
-
Save all LittleR data to
|
|
844
|
+
Save all LittleR data to Zipped Little R file.
|
|
557
845
|
|
|
558
|
-
:param file_path:
|
|
846
|
+
:param file_path: File save path.
|
|
559
847
|
:type file_path: str
|
|
560
|
-
:return:
|
|
561
|
-
:rtype:
|
|
562
848
|
"""
|
|
563
849
|
if not file_path.endswith(".zlr"):
|
|
564
850
|
file_path = f"{file_path}.zlr"
|
|
@@ -579,8 +865,8 @@ class LittleR(LittleRData):
|
|
|
579
865
|
|
|
580
866
|
:param file_path: The file path.
|
|
581
867
|
:type file_path: str
|
|
582
|
-
:return:
|
|
583
|
-
:rtype:
|
|
868
|
+
:return: ``LittleR`` instance.
|
|
869
|
+
:rtype: LittleR
|
|
584
870
|
"""
|
|
585
871
|
file_path = WRFRUNConfig.parse_resource_uri(file_path)
|
|
586
872
|
|
wrfrun/extension/utils.py
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.extension.utils
|
|
3
|
+
######################
|
|
4
|
+
|
|
5
|
+
Utility functions used by extensions.
|
|
6
|
+
|
|
7
|
+
.. autosummary::
|
|
8
|
+
:toctree: generated/
|
|
9
|
+
|
|
10
|
+
extension_postprocess
|
|
11
|
+
"""
|
|
12
|
+
|
|
1
13
|
from os import listdir
|
|
2
14
|
from os.path import exists
|
|
3
15
|
from shutil import copyfile
|
|
@@ -9,32 +21,21 @@ from wrfrun.utils import check_path, logger
|
|
|
9
21
|
|
|
10
22
|
def extension_postprocess(output_dir: str, extension_id: str, outputs: Optional[List[str]] = None):
|
|
11
23
|
"""
|
|
12
|
-
|
|
13
|
-
This function can help you save all files and logs in ``output_dir`` to the ``output_path/extension_id`` and ``output_path/extension_id/logs``,
|
|
14
|
-
``output_path`` is defined in ``config.yaml``.
|
|
15
|
-
Files end with ``.log`` are treated as log files, while others are treated as outputs.
|
|
16
|
-
You can specify outputs by giving their names through parameter ``outputs``.
|
|
24
|
+
This function provides a unified postprocessing interface for all extensions.
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
>>> extension_postprocess(output_dir_path, "ungrib")
|
|
23
|
-
|
|
24
|
-
Save outputs start with ``SST_FILE`` of ungrib.
|
|
25
|
-
|
|
26
|
-
>>> from os import listdir
|
|
27
|
-
>>> from wrfrun.extension.utils import extension_postprocess
|
|
28
|
-
>>> output_dir_path = "/WPS/outputs"
|
|
29
|
-
>>> outputs_name = [x for x in listdir(output_dir_path) if x.startswith("SST_FILE")] # type: ignore
|
|
30
|
-
>>> extension_postprocess(output_dir_path, "ungrib", outputs=outputs_name)
|
|
26
|
+
This function will save outputss and logs in ``output_dir`` to the ``{output_path}/extension_id`` and ``{output_path}/extension_id/logs``,
|
|
27
|
+
in which ``output_path`` is defined in ``config.toml``.
|
|
28
|
+
Files end with ``.log`` are treated as log files, while others are treated as outputs.
|
|
29
|
+
You can save specific outputs by giving their names through the argument ``outputs``.
|
|
31
30
|
|
|
32
31
|
:param output_dir: Absolute path of output directory.
|
|
32
|
+
:type output_dir: str
|
|
33
33
|
:param extension_id: A unique id to distinguish different extensions.
|
|
34
|
-
|
|
35
|
-
``output_path`` is defined in ``config.
|
|
34
|
+
Outputs and logs will be saved to ``{output_path}/extension_id`` and ``{output_path}/extension_id/logs``,
|
|
35
|
+
in which``output_path`` is defined in ``config.toml``.
|
|
36
|
+
:type extension_id: str
|
|
36
37
|
:param outputs: A list contains multiple filenames. Files in this will be treated as outputs.
|
|
37
|
-
:
|
|
38
|
+
:type outputs: list
|
|
38
39
|
"""
|
|
39
40
|
output_path = WRFRUNConfig.WRFRUN_OUTPUT_PATH
|
|
40
41
|
output_save_path = f"{output_path}/{extension_id}"
|
wrfrun/model/__init__.py
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
wrfrun.model
|
|
3
|
+
############
|
|
4
|
+
|
|
5
|
+
To be able to handle different numerical models,
|
|
6
|
+
``wrfrun`` implements various ``Executable`` for model's binary executable based on :class:`ExecutableBase <wrfrun.core.base.ExecutableBase>`,
|
|
7
|
+
which are all placed in this module.
|
|
8
|
+
|
|
9
|
+
``wrfrun.model`` currently supports following numerical models:
|
|
10
|
+
|
|
11
|
+
========================================= ==========================================
|
|
12
|
+
:doc:`wrf </api/model.wrf>` Support for WRF
|
|
13
|
+
========================================= ==========================================
|
|
14
|
+
|
|
15
|
+
.. toctree::
|
|
16
|
+
:maxdepth: 1
|
|
17
|
+
:hidden:
|
|
18
|
+
|
|
19
|
+
wrf <model.wrf>
|
|
20
|
+
base <model.base>
|
|
21
|
+
plot <model.plot>
|
|
22
|
+
utils <model.utils>
|
|
23
|
+
"""
|
|
24
|
+
|
|
1
25
|
from .base import *
|
|
2
26
|
from .plot import *
|
|
3
27
|
from .utils import *
|
|
4
28
|
|
|
5
29
|
# just to register executables
|
|
6
30
|
from . import wrf
|
|
7
|
-
del wrf
|