wrfrun 0.1.7__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.
Files changed (56) hide show
  1. wrfrun/cli.py +128 -0
  2. wrfrun/core/__init__.py +33 -0
  3. wrfrun/core/base.py +246 -75
  4. wrfrun/core/config.py +286 -236
  5. wrfrun/core/error.py +47 -17
  6. wrfrun/core/replay.py +65 -32
  7. wrfrun/core/server.py +139 -79
  8. wrfrun/data.py +10 -5
  9. wrfrun/extension/__init__.py +28 -0
  10. wrfrun/extension/goos_sst/__init__.py +67 -0
  11. wrfrun/extension/goos_sst/core.py +111 -0
  12. wrfrun/extension/goos_sst/res/Vtable.ERA_GOOS_SST +7 -0
  13. wrfrun/extension/goos_sst/res/__init__.py +26 -0
  14. wrfrun/extension/goos_sst/utils.py +97 -0
  15. wrfrun/extension/littler/__init__.py +57 -1
  16. wrfrun/extension/littler/{utils.py → core.py} +326 -40
  17. wrfrun/extension/utils.py +22 -21
  18. wrfrun/model/__init__.py +24 -1
  19. wrfrun/model/plot.py +253 -35
  20. wrfrun/model/utils.py +17 -8
  21. wrfrun/model/wrf/__init__.py +41 -0
  22. wrfrun/model/wrf/core.py +218 -102
  23. wrfrun/model/wrf/exec_wrap.py +49 -35
  24. wrfrun/model/wrf/namelist.py +82 -11
  25. wrfrun/model/wrf/scheme.py +85 -1
  26. wrfrun/model/wrf/{_metgrid.py → utils.py} +36 -2
  27. wrfrun/model/wrf/vtable.py +2 -1
  28. wrfrun/plot/wps.py +66 -58
  29. wrfrun/res/__init__.py +8 -5
  30. wrfrun/res/config/config.template.toml +50 -0
  31. wrfrun/res/{config.toml.template → config/wrf.template.toml} +10 -47
  32. wrfrun/res/run.template.sh +10 -0
  33. wrfrun/res/scheduler/lsf.template +5 -0
  34. wrfrun/res/{job_scheduler → scheduler}/pbs.template +1 -1
  35. wrfrun/res/{job_scheduler → scheduler}/slurm.template +2 -1
  36. wrfrun/run.py +19 -23
  37. wrfrun/scheduler/__init__.py +35 -0
  38. wrfrun/scheduler/env.py +44 -0
  39. wrfrun/scheduler/lsf.py +47 -0
  40. wrfrun/scheduler/pbs.py +48 -0
  41. wrfrun/scheduler/script.py +70 -0
  42. wrfrun/scheduler/slurm.py +48 -0
  43. wrfrun/scheduler/utils.py +14 -0
  44. wrfrun/utils.py +8 -3
  45. wrfrun/workspace/__init__.py +38 -0
  46. wrfrun/workspace/core.py +92 -0
  47. wrfrun/workspace/wrf.py +121 -0
  48. {wrfrun-0.1.7.dist-info → wrfrun-0.1.9.dist-info}/METADATA +4 -3
  49. wrfrun-0.1.9.dist-info/RECORD +62 -0
  50. wrfrun-0.1.9.dist-info/entry_points.txt +3 -0
  51. wrfrun/model/wrf/_ndown.py +0 -39
  52. wrfrun/pbs.py +0 -86
  53. wrfrun/res/run.sh.template +0 -16
  54. wrfrun/workspace.py +0 -88
  55. wrfrun-0.1.7.dist-info/RECORD +0 -46
  56. {wrfrun-0.1.7.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``, the length must contain two parameters ``(total length, decimal length)``.
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
- Head info class for LittleR format data.
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
- """Head info of little_r obs data.
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[np.ndarray, float] = 100000.,
262
- height: Union[np.ndarray, float] = -888888.,
263
- temperature: Union[np.ndarray, float] = 264.,
264
- dew_point: Union[np.ndarray, float] = 263.,
265
- wind_speed: Union[np.ndarray, float] = -888888.,
266
- wind_direction: Union[np.ndarray, float] = -888888.,
267
- wind_u: Union[np.ndarray, float] = -888888.,
268
- wind_v: Union[np.ndarray, float] = -888888.,
269
- relative_humidity: Union[np.ndarray, float] = -888888.,
270
- thickness: Union[np.ndarray, float] = -888888.,
271
- quality_control_flag: Union[np.ndarray, dict, int] = 0,
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 LittleR data from a CSV file.
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[np.ndarray, float] = 100000.,
449
- height: Union[np.ndarray, float] = -888888.,
450
- temperature: Union[np.ndarray, float] = 264.,
451
- dew_point: Union[np.ndarray, float] = 263.,
452
- wind_speed: Union[np.ndarray, float] = -888888.,
453
- wind_direction: Union[np.ndarray, float] = -888888.,
454
- wind_u: Union[np.ndarray, float] = -888888.,
455
- wind_v: Union[np.ndarray, float] = -888888.,
456
- relative_humidity: Union[np.ndarray, float] = -888888.,
457
- thickness: Union[np.ndarray, float] = -888888.,
458
- quality_control_flag: Union[np.ndarray, dict, int] = 0,
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
- """Head info of little_r obs data.
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 a ".zlr" file.
844
+ Save all LittleR data to Zipped Little R file.
557
845
 
558
- :param file_path: The save 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
- Apply postprocess after running an extension.
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
- Save all outputs of ungrib.
19
-
20
- >>> from wrfrun.extension.utils import extension_postprocess
21
- >>> output_dir_path = "/WPS/outputs"
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
- And all files and logs will be saved to ``output_path/extension_id`` and ``output_path/extension_id/logs``,
35
- ``output_path`` is defined in ``config.yaml``.
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
- :return:
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