Skip to content

Commit

Permalink
implement wgrib2-style shortcuts for accessing NAVGEM files on GODAE
Browse files Browse the repository at this point in the history
  • Loading branch information
blaylockbk committed Oct 29, 2024
1 parent 1a3a40b commit 66c7aff
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 13 deletions.
72 changes: 64 additions & 8 deletions docs/gallery/usnavy_models/navgem.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 1,
"id": "062e3c33",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -2562,6 +2562,67 @@
")"
]
},
{
"cell_type": "markdown",
"id": "e692d43d",
"metadata": {},
"source": [
"### Shortcuts\n",
"\n",
"You may use wgrib-style strings in place of the `variable` (and omit `level`) for a few common variables. Please open a pull request to add additional variables to the shortcuts. Some examples:\n",
"\n",
"- `TMP:2 m`\n",
"- `RH:2 m`\n",
"- `UGRD:10 m`\n",
"- `VGRD:10 m`\n",
"- `TMP:### mb` - Pressure levels\n",
"- `PRES:surface`"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1f017ce0",
"metadata": {},
"outputs": [
{
"ename": "AttributeError",
"evalue": "'Herbie' object has no attribute 'level'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[2], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m H \u001b[38;5;241m=\u001b[39m \u001b[43mHerbie\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m2024-01-04 00:00\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnavgem_godae\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43mvariable\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mTMP:2 m\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[43mfxx\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m6\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 6\u001b[0m \u001b[43m)\u001b[49m\n",
"File \u001b[0;32m~/GitHub.com/blaylockbk/Herbie/herbie/core.py:235\u001b[0m, in \u001b[0;36mHerbie.__init__\u001b[0;34m(self, date, valid_date, model, fxx, product, priority, save_dir, overwrite, verbose, **kwargs)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[38;5;28msetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, key, value)\n\u001b[1;32m 229\u001b[0m \u001b[38;5;66;03m# Get details from the template of the specified model.\u001b[39;00m\n\u001b[1;32m 230\u001b[0m \u001b[38;5;66;03m# This attaches the details from the `models.<model>.template`\u001b[39;00m\n\u001b[1;32m 231\u001b[0m \u001b[38;5;66;03m# class to this Herbie object.\u001b[39;00m\n\u001b[1;32m 232\u001b[0m \u001b[38;5;66;03m# This line is equivalent to `model_templates.gfs.template(self)`.\u001b[39;00m\n\u001b[1;32m 233\u001b[0m \u001b[38;5;66;03m# I do it this way because the model name is a variable.\u001b[39;00m\n\u001b[1;32m 234\u001b[0m \u001b[38;5;66;03m# (see https://stackoverflow.com/a/7936588/2383070 for what I'm doing here)\u001b[39;00m\n\u001b[0;32m--> 235\u001b[0m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mmodel_templates\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmodel\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtemplate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 237\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m product \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 238\u001b[0m \u001b[38;5;66;03m# The user didn't specify a product, so let's use the first\u001b[39;00m\n\u001b[1;32m 239\u001b[0m \u001b[38;5;66;03m# product in the model template.\u001b[39;00m\n\u001b[1;32m 240\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mproduct \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mlist\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mPRODUCTS)[\u001b[38;5;241m0\u001b[39m]\n",
"File \u001b[0;32m~/GitHub.com/blaylockbk/Herbie/herbie/models/usnavy.py:35\u001b[0m, in \u001b[0;36mnavgem_godae.template\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mPRODUCTS \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 28\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGMET\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 29\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGLND\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 30\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mGCOM\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 31\u001b[0m }\n\u001b[1;32m 33\u001b[0m \u001b[38;5;66;03m# Please review https://usgodae.org/docs/layout/mdllayout.pns.html\u001b[39;00m\n\u001b[1;32m 34\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mSOURCES \u001b[38;5;241m=\u001b[39m {\n\u001b[0;32m---> 35\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnavgem\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdate\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m%Y/%Y%m%d%H\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/US058\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mproduct\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m-GR1mdl.0018_0056_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfxx\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m03d\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m00F0RL\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdate\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m%Y%m%d%H\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlevel\u001b[49m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvariable\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 36\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnogaps\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhttps://usgodae.org/ftp/outgoing/fnmoc/models/nogaps/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdate\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m%Y/%Y%m%d%H\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/US058\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mproduct\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m-GR1mdl.0058_0240_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfxx\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m03d\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m00F0RL\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdate\u001b[38;5;132;01m:\u001b[39;00m\u001b[38;5;124m%Y%m%d%H\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m_\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlevel\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mvariable\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 37\u001b[0m }\n\u001b[1;32m 38\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mLOCALFILE \u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_remoteFileName\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n",
"\u001b[0;31mAttributeError\u001b[0m: 'Herbie' object has no attribute 'level'"
]
}
],
"source": [
"H = Herbie(\n",
" \"2024-01-04 00:00\",\n",
" model=\"navgem_godae\",\n",
" variable=\"TMP:2 m\",\n",
" fxx=6,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68ffa21f",
"metadata": {},
"outputs": [],
"source": [
"H = Herbie(\n",
" \"2024-01-04 00:00\",\n",
" model=\"navgem_godae\",\n",
" variable=\"RH:500 mb\",\n",
" fxx=6,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "978ca0ab",
Expand Down Expand Up @@ -3115,7 +3176,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "herbie-dev",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
Expand All @@ -3129,12 +3190,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.2"
},
"vscode": {
"interpreter": {
"hash": "ac511961bc6976a3d289cde8fc247e6b0e9298cf513cb762aa0a7df646d192ed"
}
"version": "3.12.7"
}
},
"nbformat": 4,
Expand Down
71 changes: 66 additions & 5 deletions herbie/models/usnavy.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,77 @@ def template(self):
"godae": "https://usgodae.org/",
"filename_description": "https://usgodae.org/docs/layout/mdllayout.pns.html",
}
self.PRODUCTS = {
"GMET": "",
"GLND": "",
"GCOM": "",

if self.variable == "HGT:surface":
# Special case for terrain height
self.PRODUCTS = {
"GLND": "Land fields (terrain)",
}
else:
self.PRODUCTS = {
"GMET": "Meteorological fields",
"GLND": "Land fields (terrain)",
"GOCN": "Ocean fields",
"GCOM": "?",
}

# Facilitate familiar shortcuts using wgrib2-style terms to allow
# - `variable='TMP:2 m'`
# - `variable='TMP:500 mb'`
# - `variable='UGRD:10 m'`
# - `variable='SNOD:surface'`
# See https://usgodae.org/docs/layout/pn_level_type_tbl.pns.html

# Map of wgrib2 variable names to GODAE variable names
variable_map = {
"TMP": "air_temp", # Air temperature
"DEPR": "dwpt_dprs", # Dew point depression
"ABSV": "abs_vort", # Absolute vorticity
"RH": "rltv_hum", # Relative Humidity
"PRES": "pres", # Pressure
"UGRD": "wnd_ucmp", # Wind u-component
"VGRD": "wnd_vcmp", # Wind v-component
"HGT": "geop_ht", # Geopotential height
"VAPP": "vpr_pres", # Vapor pressure
"VVEL": "wnd_vert_vel", # Vertical velocity
"CAPE": "cape", # CAPE
"VIS": "visib", # Visibility
"PWAT": "prcp_h20", # Precipitable water (use PWAT:surface)
"PRATE": "rain_rate", # Precipitation rate
"SHTFL": "snsb_heat_flux", # Sensible heat flux
"SNOD": "snw_dpth", # Snow depth
"NSWRS": "sol_rad", # Net short-wave radiation flux
"UFLX": "wnd_strs_ucmp", # Momentum flux, u-component
"VFLX": "wnd_strs_vcmp", # Momentum flux, v-component
"PRMSL": "pres_msl", # Mean sea level pressure
}

# Please review https://usgodae.org/docs/layout/mdllayout.pns.html
if ":" in self.variable:
var, lev = self.variable.split(":", maxsplit=1)
self.variable = variable_map.get(var)
if var == "HGT" and lev == "surface":
self.level = "0001_000000-000000"
self.variable = "terr_ht"
elif var in {"MSLMA", "PRMSL"}:
self.level = "0102_000000-000000"
elif lev.endswith("mb"):
lev = int(lev.strip("mb").strip())
self.level = f"0100_{lev:06d}-000000"
elif lev == "2 m":
self.level = "0105_000020-000000"
elif lev == "10 m":
self.level = "0105_000100-000000"
elif lev == "surface":
self.level = "0001_000000-000000"
elif lev in {"0C", "0C isotherm"}:
self.level = "0006_000000-000000"
elif lev in {"tropopause"}:
self.level = "0007_000000-000000"

self.SOURCES = {
"navgem": f"https://usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/{self.date:%Y/%Y%m%d%H}/US058{self.product}-GR1mdl.0018_0056_{self.fxx:03d}00F0RL{self.date:%Y%m%d%H}_{self.level}{self.variable}",
"nogaps": f"https://usgodae.org/ftp/outgoing/fnmoc/models/nogaps/{self.date:%Y/%Y%m%d%H}/US058{self.product}-GR1mdl.0058_0240_{self.fxx:03d}00F0RL{self.date:%Y%m%d%H}_{self.level}{self.variable}",
"navgem grib2": f"https://usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/{self.date:%Y/%Y%m%d%H}/US058{self.product}-GR2mdl.0018_0056_{self.fxx:03d}00F0RL{self.date:%Y%m%d%H}_{self.level}{self.variable}.gr2",
}
self.LOCALFILE = f"{self.get_remoteFileName}"

Expand Down

0 comments on commit 66c7aff

Please sign in to comment.