herbiedss 0.1.0__tar.gz
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.
- herbiedss-0.1.0/PKG-INFO +121 -0
- herbiedss-0.1.0/README.md +103 -0
- herbiedss-0.1.0/pyproject.toml +38 -0
- herbiedss-0.1.0/pyproject.toml.orig +35 -0
- herbiedss-0.1.0/src/herbiedss/__init__.py +0 -0
- herbiedss-0.1.0/src/herbiedss/__main__.py +3 -0
- herbiedss-0.1.0/src/herbiedss/grid/__init__.py +0 -0
- herbiedss-0.1.0/src/herbiedss/grid/download.py +142 -0
- herbiedss-0.1.0/src/herbiedss/grid/dssexport.py +577 -0
- herbiedss-0.1.0/src/herbiedss/grid/inventory.py +144 -0
- herbiedss-0.1.0/src/herbiedss/main.py +47 -0
- herbiedss-0.1.0/src/herbiedss/options.py +162 -0
- herbiedss-0.1.0/src/herbiedss/state.py +44 -0
- herbiedss-0.1.0/src/herbiedss/utils/__init__.py +0 -0
- herbiedss-0.1.0/src/herbiedss/utils/reproject.py +328 -0
- herbiedss-0.1.0/src/herbiedss/utils/validate.py +138 -0
herbiedss-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: herbiedss
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Fetch NOAA weather model output (HRRR, GFS, GEFS) with Herbie, reproject to USACE SHG or NWS HRAP hydrologic grids, clip to a watershed boundary, and write the result to HEC-DSS for use in HEC-HMS/HEC-RAS.
|
|
5
|
+
Keywords: herbie,hec-dss,hydrology,grib,shg,hrap,hrrr,gfs,noaa
|
|
6
|
+
Author: Jeff Gregory
|
|
7
|
+
Author-email: Jeff Gregory <jeffrey.s.gregory@usace.army.mil>
|
|
8
|
+
Requires-Dist: geopandas>=1.1.4
|
|
9
|
+
Requires-Dist: hecdss>=0.1.32
|
|
10
|
+
Requires-Dist: herbie-data>=2026.3.0
|
|
11
|
+
Requires-Dist: pyproj>=3.7.2
|
|
12
|
+
Requires-Dist: rasterio>=1.5.1
|
|
13
|
+
Requires-Dist: rich>=15.0.0
|
|
14
|
+
Requires-Dist: rioxarray>=0.23.0
|
|
15
|
+
Requires-Dist: typer>=0.27.1
|
|
16
|
+
Requires-Python: >=3.13
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# herbiedss
|
|
20
|
+
|
|
21
|
+
A command-line tool that fetches NOAA weather model output (HRRR, GFS, GEFS, and other models supported by [Herbie](https://github.com/blaylockbk/Herbie)), optionally reprojects it onto the USACE **Standard Hydrologic Grid (SHG)** or the NWS **Hydrologic Rainfall Analysis Project (HRAP)** grid, clips it to a watershed boundary, and writes the result into a **HEC-DSS** file for use in HEC-HMS, HEC-RAS, or other USACE modeling tools.
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Downloads GRIB2 model output via Herbie for any date, forecast hour, model, and product combination.
|
|
26
|
+
- Filters GRIB messages with regex search strings against Herbie's inventory, so you can target specific fields like hourly (not cumulative) accumulated precipitation.
|
|
27
|
+
- Reprojects the native model grid (e.g. HRRR's Lambert Conformal, GFS/GEFS's regular lat-lon) onto SHG (Albers Equal-Area, 2000 m native cell size) or HRAP (polar stereographic, 4762.5 m native cell size).
|
|
28
|
+
- Handles both rectilinear (1D lat/lon) and curvilinear (2D lat/lon) source grids automatically.
|
|
29
|
+
- Clips the reprojected grid to a user-supplied watershed boundary file (shapefile, GeoJSON, GeoPackage, or anything GeoPandas can read), regardless of that file's own CRS.
|
|
30
|
+
- Writes each grid to HEC-DSS with a pathname whose D/E parts are derived from the grid's own start/end time, so instantaneous and accumulated fields are timestamped correctly.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install herbiedss
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Requires Python 3.10+. Core dependencies include `herbie-data`, `hecdss`, `rioxarray`, `pyproj`, `geopandas`, `typer`, and `rich`.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
### Basic export (native model projection)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
herbiedss dssexport \\
|
|
46
|
+
--date 2026-08-18 \\
|
|
47
|
+
--model hrrr \\
|
|
48
|
+
--fxx 6 \\
|
|
49
|
+
--search ":TMP:2 m above ground:" \\
|
|
50
|
+
--dssfile output.dss \\
|
|
51
|
+
--apart HRRR --bpart CONUS --cpart TMP2M
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Reproject to SHG and clip to a watershed
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
herbiedss dssexport \\
|
|
58
|
+
--date 2026-08-18 \\
|
|
59
|
+
--model hrrr \\
|
|
60
|
+
--fxx 6 \\
|
|
61
|
+
--search ":APCP:.*:(?:0-1|[1-9]\\d*-\\d+) hour" \\
|
|
62
|
+
--grid-system shg \\
|
|
63
|
+
--boundary-file watershed.shp \\
|
|
64
|
+
--dssfile output.dss \\
|
|
65
|
+
--apart SHG --bpart TRINITY --cpart PRECIP
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Reproject to HRAP without clipping
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
herbiedss dssexport \\
|
|
72
|
+
--date 2026-08-18 \\
|
|
73
|
+
--model gfs \\
|
|
74
|
+
--fxx 12 \\
|
|
75
|
+
--grid-system hrap \\
|
|
76
|
+
--dssfile output.dss \\
|
|
77
|
+
--apart HRAP --bpart CONUS --cpart PRECIP
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## CLI Options
|
|
81
|
+
|
|
82
|
+
| Option | Description |
|
|
83
|
+
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| `--date` | Forecast initialization date(s). Accepts a separator-delimited list via `--sep`. |
|
|
85
|
+
| `--model` | Herbie model name (`hrrr`, `gfs`, `gefs`, etc.). Default: `hrrr`. |
|
|
86
|
+
| `--product` | Model product/subset (e.g. `sfc`). Default: `sfc`. |
|
|
87
|
+
| `--fxx` | Forecast lead hour(s). Accepts a separator-delimited list. |
|
|
88
|
+
| `--search` | Regex pattern to filter Herbie's GRIB inventory (passed to `.xarray(search=...)`). |
|
|
89
|
+
| `--variable` | Explicit xarray variable name, if `--search` matches more than one. |
|
|
90
|
+
| `--grid-system` | Reproject onto `shg` or `hrap` before writing to DSS. Omit to keep the model's native projection. |
|
|
91
|
+
| `--boundary-file` | Path to a watershed boundary vector file. Requires `--grid-system`. |
|
|
92
|
+
| `--dssfile` | Output HEC-DSS file path. Default: `herbiedss.dss`. |
|
|
93
|
+
| `--apart`, `--bpart`, `--cpart`, `--fpart` | DSS pathname A/B/C/F parts. D and E parts are derived automatically from the grid's own timing metadata. |
|
|
94
|
+
| `--save-dir` | Local directory for downloaded GRIB2 files. |
|
|
95
|
+
| `--remove-grib` | Delete the local GRIB2 file after loading it into xarray. |
|
|
96
|
+
| `--overwrite` | Re-download and overwrite existing local GRIB2 files. |
|
|
97
|
+
| `--verbose` | Enable verbose Herbie logging. |
|
|
98
|
+
|
|
99
|
+
## How Reprojection Works
|
|
100
|
+
|
|
101
|
+
Herbie's `.xarray()` accessor exposes each model's native coordinate reference system via `da.herbie.crs` (a Cartopy CRS). The `herbiedss.utils.reproject` module converts that to a `pyproj` CRS, attaches it to the DataArray with `rioxarray`, and calls `.rio.reproject()` onto one of two hardcoded target CRS definitions, since neither has a standard EPSG code:
|
|
102
|
+
|
|
103
|
+
- **SHG**: `+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +datum=NAD83 +units=m`
|
|
104
|
+
- **HRAP**: `+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +R=6371200 +units=m`
|
|
105
|
+
|
|
106
|
+
Model grids come in two shapes, handled automatically:
|
|
107
|
+
|
|
108
|
+
- **Rectilinear** grids (GFS, GEFS): latitude/longitude are already 1D dimension coordinates, so renaming to `x`/`y` is direct.
|
|
109
|
+
- **Curvilinear** grids (HRRR's native Lambert Conformal): latitude/longitude are 2D auxiliary coordinates. The module looks for an existing 1D projected coordinate under alternate names, or reconstructs one by round-tripping a row/column of the 2D lat/lon through the source CRS.
|
|
110
|
+
|
|
111
|
+
Clipping to a watershed boundary happens *after* reprojection, using `.rio.clip()` with the boundary file's geometry reprojected to match the target grid's CRS — this is a separate step from reprojection and works with any vector format GeoPandas supports, not just rasters.
|
|
112
|
+
|
|
113
|
+
## Known Limitations
|
|
114
|
+
|
|
115
|
+
- `hecdss.GriddedData` attribute names for grid reference system, cell size, and lower-left origin vary by installed `hecdss` version. The export step attaches these defensively via `hasattr()` checks — verify with `dir(GriddedData())` on your installed version if georeferencing isn't showing up correctly in the output DSS file.
|
|
116
|
+
- Accumulated fields (e.g. `APCP`) can have multiple GRIB messages with overlapping-looking inventory strings (`0-2 hour` vs. `1-2 hour`). Always test your `--search` regex with `H.inventory(search)` before running a full export, since an imprecise pattern can silently match the wrong accumulation window.
|
|
117
|
+
- HRAP and SHG are both undefined outside the conterminous United States; reprojecting global or non-CONUS domains onto either grid will produce questionable results.
|
|
118
|
+
|
|
119
|
+
## License
|
|
120
|
+
|
|
121
|
+
MIT
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# herbiedss
|
|
2
|
+
|
|
3
|
+
A command-line tool that fetches NOAA weather model output (HRRR, GFS, GEFS, and other models supported by [Herbie](https://github.com/blaylockbk/Herbie)), optionally reprojects it onto the USACE **Standard Hydrologic Grid (SHG)** or the NWS **Hydrologic Rainfall Analysis Project (HRAP)** grid, clips it to a watershed boundary, and writes the result into a **HEC-DSS** file for use in HEC-HMS, HEC-RAS, or other USACE modeling tools.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Downloads GRIB2 model output via Herbie for any date, forecast hour, model, and product combination.
|
|
8
|
+
- Filters GRIB messages with regex search strings against Herbie's inventory, so you can target specific fields like hourly (not cumulative) accumulated precipitation.
|
|
9
|
+
- Reprojects the native model grid (e.g. HRRR's Lambert Conformal, GFS/GEFS's regular lat-lon) onto SHG (Albers Equal-Area, 2000 m native cell size) or HRAP (polar stereographic, 4762.5 m native cell size).
|
|
10
|
+
- Handles both rectilinear (1D lat/lon) and curvilinear (2D lat/lon) source grids automatically.
|
|
11
|
+
- Clips the reprojected grid to a user-supplied watershed boundary file (shapefile, GeoJSON, GeoPackage, or anything GeoPandas can read), regardless of that file's own CRS.
|
|
12
|
+
- Writes each grid to HEC-DSS with a pathname whose D/E parts are derived from the grid's own start/end time, so instantaneous and accumulated fields are timestamped correctly.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install herbiedss
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Requires Python 3.10+. Core dependencies include `herbie-data`, `hecdss`, `rioxarray`, `pyproj`, `geopandas`, `typer`, and `rich`.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
### Basic export (native model projection)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
herbiedss dssexport \\
|
|
28
|
+
--date 2026-08-18 \\
|
|
29
|
+
--model hrrr \\
|
|
30
|
+
--fxx 6 \\
|
|
31
|
+
--search ":TMP:2 m above ground:" \\
|
|
32
|
+
--dssfile output.dss \\
|
|
33
|
+
--apart HRRR --bpart CONUS --cpart TMP2M
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Reproject to SHG and clip to a watershed
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
herbiedss dssexport \\
|
|
40
|
+
--date 2026-08-18 \\
|
|
41
|
+
--model hrrr \\
|
|
42
|
+
--fxx 6 \\
|
|
43
|
+
--search ":APCP:.*:(?:0-1|[1-9]\\d*-\\d+) hour" \\
|
|
44
|
+
--grid-system shg \\
|
|
45
|
+
--boundary-file watershed.shp \\
|
|
46
|
+
--dssfile output.dss \\
|
|
47
|
+
--apart SHG --bpart TRINITY --cpart PRECIP
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Reproject to HRAP without clipping
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
herbiedss dssexport \\
|
|
54
|
+
--date 2026-08-18 \\
|
|
55
|
+
--model gfs \\
|
|
56
|
+
--fxx 12 \\
|
|
57
|
+
--grid-system hrap \\
|
|
58
|
+
--dssfile output.dss \\
|
|
59
|
+
--apart HRAP --bpart CONUS --cpart PRECIP
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## CLI Options
|
|
63
|
+
|
|
64
|
+
| Option | Description |
|
|
65
|
+
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
|
|
66
|
+
| `--date` | Forecast initialization date(s). Accepts a separator-delimited list via `--sep`. |
|
|
67
|
+
| `--model` | Herbie model name (`hrrr`, `gfs`, `gefs`, etc.). Default: `hrrr`. |
|
|
68
|
+
| `--product` | Model product/subset (e.g. `sfc`). Default: `sfc`. |
|
|
69
|
+
| `--fxx` | Forecast lead hour(s). Accepts a separator-delimited list. |
|
|
70
|
+
| `--search` | Regex pattern to filter Herbie's GRIB inventory (passed to `.xarray(search=...)`). |
|
|
71
|
+
| `--variable` | Explicit xarray variable name, if `--search` matches more than one. |
|
|
72
|
+
| `--grid-system` | Reproject onto `shg` or `hrap` before writing to DSS. Omit to keep the model's native projection. |
|
|
73
|
+
| `--boundary-file` | Path to a watershed boundary vector file. Requires `--grid-system`. |
|
|
74
|
+
| `--dssfile` | Output HEC-DSS file path. Default: `herbiedss.dss`. |
|
|
75
|
+
| `--apart`, `--bpart`, `--cpart`, `--fpart` | DSS pathname A/B/C/F parts. D and E parts are derived automatically from the grid's own timing metadata. |
|
|
76
|
+
| `--save-dir` | Local directory for downloaded GRIB2 files. |
|
|
77
|
+
| `--remove-grib` | Delete the local GRIB2 file after loading it into xarray. |
|
|
78
|
+
| `--overwrite` | Re-download and overwrite existing local GRIB2 files. |
|
|
79
|
+
| `--verbose` | Enable verbose Herbie logging. |
|
|
80
|
+
|
|
81
|
+
## How Reprojection Works
|
|
82
|
+
|
|
83
|
+
Herbie's `.xarray()` accessor exposes each model's native coordinate reference system via `da.herbie.crs` (a Cartopy CRS). The `herbiedss.utils.reproject` module converts that to a `pyproj` CRS, attaches it to the DataArray with `rioxarray`, and calls `.rio.reproject()` onto one of two hardcoded target CRS definitions, since neither has a standard EPSG code:
|
|
84
|
+
|
|
85
|
+
- **SHG**: `+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +datum=NAD83 +units=m`
|
|
86
|
+
- **HRAP**: `+proj=stere +lat_0=90 +lat_ts=60 +lon_0=-105 +R=6371200 +units=m`
|
|
87
|
+
|
|
88
|
+
Model grids come in two shapes, handled automatically:
|
|
89
|
+
|
|
90
|
+
- **Rectilinear** grids (GFS, GEFS): latitude/longitude are already 1D dimension coordinates, so renaming to `x`/`y` is direct.
|
|
91
|
+
- **Curvilinear** grids (HRRR's native Lambert Conformal): latitude/longitude are 2D auxiliary coordinates. The module looks for an existing 1D projected coordinate under alternate names, or reconstructs one by round-tripping a row/column of the 2D lat/lon through the source CRS.
|
|
92
|
+
|
|
93
|
+
Clipping to a watershed boundary happens *after* reprojection, using `.rio.clip()` with the boundary file's geometry reprojected to match the target grid's CRS — this is a separate step from reprojection and works with any vector format GeoPandas supports, not just rasters.
|
|
94
|
+
|
|
95
|
+
## Known Limitations
|
|
96
|
+
|
|
97
|
+
- `hecdss.GriddedData` attribute names for grid reference system, cell size, and lower-left origin vary by installed `hecdss` version. The export step attaches these defensively via `hasattr()` checks — verify with `dir(GriddedData())` on your installed version if georeferencing isn't showing up correctly in the output DSS file.
|
|
98
|
+
- Accumulated fields (e.g. `APCP`) can have multiple GRIB messages with overlapping-looking inventory strings (`0-2 hour` vs. `1-2 hour`). Always test your `--search` regex with `H.inventory(search)` before running a full export, since an imprecise pattern can silently match the wrong accumulation window.
|
|
99
|
+
- HRAP and SHG are both undefined outside the conterminous United States; reprojecting global or non-CONUS domains onto either grid will produce questionable results.
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
MIT
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "herbiedss"
|
|
3
|
+
readme = "README.md"
|
|
4
|
+
version = "0.1.0"
|
|
5
|
+
description = "Fetch NOAA weather model output (HRRR, GFS, GEFS) with Herbie, reproject to USACE SHG or NWS HRAP hydrologic grids, clip to a watershed boundary, and write the result to HEC-DSS for use in HEC-HMS/HEC-RAS."
|
|
6
|
+
keywords = [
|
|
7
|
+
"herbie",
|
|
8
|
+
"hec-dss",
|
|
9
|
+
"hydrology",
|
|
10
|
+
"grib",
|
|
11
|
+
"shg",
|
|
12
|
+
"hrap",
|
|
13
|
+
"hrrr",
|
|
14
|
+
"gfs",
|
|
15
|
+
"noaa",
|
|
16
|
+
]
|
|
17
|
+
requires-python = ">=3.13"
|
|
18
|
+
dependencies = [
|
|
19
|
+
"geopandas>=1.1.4",
|
|
20
|
+
"hecdss>=0.1.32",
|
|
21
|
+
"herbie-data>=2026.3.0",
|
|
22
|
+
"pyproj>=3.7.2",
|
|
23
|
+
"rasterio>=1.5.1",
|
|
24
|
+
"rich>=15.0.0",
|
|
25
|
+
"rioxarray>=0.23.0",
|
|
26
|
+
"typer>=0.27.1",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[[project.authors]]
|
|
30
|
+
name = "Jeff Gregory"
|
|
31
|
+
email = "jeffrey.s.gregory@usace.army.mil"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
herbiedss = "herbiedss.main:app"
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
38
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "herbiedss"
|
|
3
|
+
readme = "README.md"
|
|
4
|
+
version = "0.1.0"
|
|
5
|
+
description = "Fetch NOAA weather model output (HRRR, GFS, GEFS) with Herbie, reproject to USACE SHG or NWS HRAP hydrologic grids, clip to a watershed boundary, and write the result to HEC-DSS for use in HEC-HMS/HEC-RAS."
|
|
6
|
+
keywords = [
|
|
7
|
+
"herbie",
|
|
8
|
+
"hec-dss",
|
|
9
|
+
"hydrology",
|
|
10
|
+
"grib",
|
|
11
|
+
"shg",
|
|
12
|
+
"hrap",
|
|
13
|
+
"hrrr",
|
|
14
|
+
"gfs",
|
|
15
|
+
"noaa",
|
|
16
|
+
]
|
|
17
|
+
authors = [{ name = "Jeff Gregory", email = "jeffrey.s.gregory@usace.army.mil" }]
|
|
18
|
+
requires-python = ">=3.13"
|
|
19
|
+
dependencies = [
|
|
20
|
+
"geopandas>=1.1.4",
|
|
21
|
+
"hecdss>=0.1.32",
|
|
22
|
+
"herbie-data>=2026.3.0",
|
|
23
|
+
"pyproj>=3.7.2",
|
|
24
|
+
"rasterio>=1.5.1",
|
|
25
|
+
"rich>=15.0.0",
|
|
26
|
+
"rioxarray>=0.23.0",
|
|
27
|
+
"typer>=0.27.1",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
herbiedss = "herbiedss.main:app"
|
|
32
|
+
|
|
33
|
+
[build-system]
|
|
34
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
35
|
+
build-backend = "uv_build"
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
download.py
|
|
3
|
+
|
|
4
|
+
Typer command that downloads GRIB2 model output (optionally subset to
|
|
5
|
+
specific fields) using the `Herbie` package, iterating over every
|
|
6
|
+
date/forecast-hour combination requested on the command line.
|
|
7
|
+
|
|
8
|
+
Raises
|
|
9
|
+
------
|
|
10
|
+
typer.Exit
|
|
11
|
+
Raised with exit code 1 if `Herbie.download` fails for any requested
|
|
12
|
+
date/forecast-hour combination (e.g. the file is not found at any
|
|
13
|
+
known archive source, or a network/IO error occurs).
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import typer
|
|
17
|
+
from herbie.core import Herbie
|
|
18
|
+
from rich.console import Console
|
|
19
|
+
|
|
20
|
+
from herbiedss.utils.validate import parse_date_values, parse_option_values
|
|
21
|
+
|
|
22
|
+
from ..options import (
|
|
23
|
+
DateOption,
|
|
24
|
+
FxxOption,
|
|
25
|
+
ModelOption,
|
|
26
|
+
OverwriteOption,
|
|
27
|
+
ProductOption,
|
|
28
|
+
SaveDirOption,
|
|
29
|
+
SepOption,
|
|
30
|
+
SubsetOption,
|
|
31
|
+
VerboseOption,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
console = Console()
|
|
35
|
+
error_console = Console(stderr=True, style="bold red")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# @app.command()
|
|
39
|
+
def download(
|
|
40
|
+
# ctx: typer.Context,
|
|
41
|
+
date: DateOption,
|
|
42
|
+
model: ModelOption = "hrrr",
|
|
43
|
+
product: ProductOption = "sfc",
|
|
44
|
+
fxx: FxxOption = "0",
|
|
45
|
+
sep: SepOption = ",",
|
|
46
|
+
save_dir: SaveDirOption = None,
|
|
47
|
+
subset: SubsetOption = None,
|
|
48
|
+
verbose: VerboseOption = False,
|
|
49
|
+
overwrite: OverwriteOption = False,
|
|
50
|
+
) -> None:
|
|
51
|
+
"""Download the GRIB2 file (optionally subset) for the given date/model/fxx.
|
|
52
|
+
|
|
53
|
+
For every combination of model run date and forecast lead time (fxx),
|
|
54
|
+
this command builds a `Herbie` object and downloads the corresponding
|
|
55
|
+
GRIB2 file from whichever archive source (NOMADS, AWS, Google Cloud,
|
|
56
|
+
Azure, ECMWF, Pando, etc.) has it available. If a `subset` search
|
|
57
|
+
string is supplied, only the matching GRIB messages (fields) are
|
|
58
|
+
downloaded instead of the full file, which saves bandwidth and disk
|
|
59
|
+
space.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
date : DateOption
|
|
64
|
+
One or more model initialization dates/times to download, as a
|
|
65
|
+
separator-delimited string (see `sep`). Parsed via
|
|
66
|
+
`parse_date_values` into a list of date strings that `Herbie`
|
|
67
|
+
can interpret (e.g. "2024-01-01 12:00").
|
|
68
|
+
model : ModelOption, optional
|
|
69
|
+
Name of the NWP model to download, as defined in Herbie's model
|
|
70
|
+
template folder (e.g. "hrrr", "hrrrak", "rap", "gfs", "ecmwf").
|
|
71
|
+
Case-insensitive. Defaults to "hrrr".
|
|
72
|
+
product : ProductOption, optional
|
|
73
|
+
Output variable product/file type for the model (e.g. "sfc" for
|
|
74
|
+
surface, "prs" for pressure levels, "nat", "subh"). Case-sensitive
|
|
75
|
+
and model-dependent. Defaults to "sfc".
|
|
76
|
+
fxx : FxxOption, optional
|
|
77
|
+
One or more forecast lead times in hours, as a separator-delimited
|
|
78
|
+
string (see `sep`). Parsed via `parse_option_values` into a list
|
|
79
|
+
of integers. Available lead times depend on the model and model
|
|
80
|
+
version. Defaults to "0" (the analysis/initialization hour).
|
|
81
|
+
sep : SepOption, optional
|
|
82
|
+
Delimiter used to split multiple values passed to `date` and
|
|
83
|
+
`fxx` into lists. Defaults to ",".
|
|
84
|
+
save_dir : SaveDirOption, optional
|
|
85
|
+
Local directory in which to save downloaded files. If `None`,
|
|
86
|
+
Herbie's default data directory (from its configuration) is
|
|
87
|
+
used instead.
|
|
88
|
+
subset : SubsetOption, optional
|
|
89
|
+
Regular-expression search string used to filter GRIB messages by
|
|
90
|
+
variable/level (e.g. ":TMP:2 m" or ":500 mb"), matched against the
|
|
91
|
+
file's index (.idx) entries. If provided, only the matching
|
|
92
|
+
messages are downloaded via `Herbie.download(search=subset)`;
|
|
93
|
+
if `None`, the full GRIB2 file is downloaded.
|
|
94
|
+
verbose : VerboseOption, optional
|
|
95
|
+
If `True`, print additional diagnostic output while locating and
|
|
96
|
+
downloading each file. Defaults to `False`.
|
|
97
|
+
overwrite : OverwriteOption, optional
|
|
98
|
+
If `True`, re-download and overwrite the file even if it already
|
|
99
|
+
exists locally. If `False`, an existing local copy is reused.
|
|
100
|
+
Defaults to `False`.
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
None
|
|
105
|
+
This command does not return a value. For each successfully
|
|
106
|
+
downloaded file, the resolved local path is printed to stdout
|
|
107
|
+
via `console.print`.
|
|
108
|
+
|
|
109
|
+
Raises
|
|
110
|
+
------
|
|
111
|
+
typer.Exit
|
|
112
|
+
Raised with exit code 1 if `Herbie.download` raises any exception
|
|
113
|
+
for a given date/fxx combination. The triggering exception's
|
|
114
|
+
message is printed to stderr before exiting.
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
resolved_date: list[str] = parse_date_values(date, sep)
|
|
118
|
+
resolved_fxx: list[int] = parse_option_values(fxx, sep)
|
|
119
|
+
|
|
120
|
+
for dt in resolved_date:
|
|
121
|
+
for hr in resolved_fxx:
|
|
122
|
+
kwargs = {
|
|
123
|
+
"date": dt,
|
|
124
|
+
"model": model,
|
|
125
|
+
"product": product,
|
|
126
|
+
"fxx": hr,
|
|
127
|
+
"verbose": verbose,
|
|
128
|
+
"overwrite": overwrite,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if save_dir is not None:
|
|
132
|
+
kwargs["save_dir"] = str(save_dir)
|
|
133
|
+
|
|
134
|
+
H = Herbie(**kwargs)
|
|
135
|
+
|
|
136
|
+
try:
|
|
137
|
+
path = H.download(search=subset) if subset else H.download()
|
|
138
|
+
except Exception as exc: # noqa: BLE001
|
|
139
|
+
error_console.print(f"Download failed: {exc}")
|
|
140
|
+
raise typer.Exit(code=1)
|
|
141
|
+
|
|
142
|
+
console.print(f"[green]Saved:[/green] {path}")
|