Skip to content

Commit 730f105

Browse files
committed
moved navy models to own file
1 parent 26949ca commit 730f105

4 files changed

Lines changed: 214 additions & 190 deletions

File tree

src/herbie/v2/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,17 @@
6060
# NOAA ensemble / specialty
6161
from herbie.v2.models.more_models import AIGFS, CFS, HGEFS, HREF, NBMQMD
6262

63-
# Hurricane / Navy
64-
from herbie.v2.models.hurricane_and_navy import (
63+
# Hurricane
64+
from herbie.v2.models.hurricane import (
6565
HAFSA,
6666
HAFSB,
6767
HIRESW,
68-
NavgemGODAE,
69-
NavgemNOMADS,
68+
)
69+
70+
# Navy
71+
from herbie.v2.models.navy import (
72+
NAVGEM_GODAE,
73+
NAVGEM,
7074
)
7175

7276
# ECMWF

src/herbie/v2/_namespace.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,17 @@
4848
# ── NOAA ensemble / specialty ─────────────────────────────────────────
4949
from herbie.v2.models.more_models import AIGFS, CFS, HGEFS, HREF, NBMQMD
5050

51-
# ── Hurricane / Navy ──────────────────────────────────────────────────
52-
from herbie.v2.models.hurricane_and_navy import (
51+
# ── Hurricane -------──────────────────────────────────────────────────
52+
from herbie.v2.models.hurricane import (
5353
HAFSA,
5454
HAFSB,
5555
HIRESW,
56-
NavgemGODAE,
57-
NavgemNOMADS,
56+
)
57+
58+
# ── Navy ------------──────────────────────────────────────────────────
59+
from herbie.v2.models.navy import (
60+
NAVGEM_GODAE,
61+
NAVGEM,
5862
)
5963

6064
# ── ECMWF ─────────────────────────────────────────────────────────────
@@ -86,6 +90,8 @@ class Herbie:
8690
Herbie.NBM — National Blend of Models
8791
Herbie.GEFS — Global Ensemble Forecast System
8892
Herbie.RRFS — Rapid Refresh Forecast System
93+
Herbie.NAVGEM_GODAE — NAVGEM from GODAE
94+
Herbie.NAVGEM — NAVGEM from NOMADS
8995
9096
Each model class can also be imported directly::
9197
@@ -127,12 +133,14 @@ class Herbie:
127133
HREF: ClassVar[type[HREF]]
128134
NBMQMD: ClassVar[type[NBMQMD]]
129135

130-
# Hurricane / Navy
136+
# Hurricane
131137
HAFSA: ClassVar[type[HAFSA]]
132138
HAFSB: ClassVar[type[HAFSB]]
133139
HIRESW: ClassVar[type[HIRESW]]
134-
NavgemNOMADS: ClassVar[type[NavgemNOMADS]]
135-
NavgemGODAE: ClassVar[type[NavgemGODAE]]
140+
141+
# Navy
142+
NAVGEM: ClassVar[type[NAVGEM]]
143+
NAVGEM_GODAE: ClassVar[type[NAVGEM_GODAE]]
136144

137145
# ECMWF
138146
IFS: ClassVar[type[IFS]]

src/herbie/v2/models/hurricane_and_navy.py renamed to src/herbie/v2/models/hurricane.py

Lines changed: 0 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -269,182 +269,3 @@ def _build_sources(self) -> dict:
269269
}
270270

271271

272-
# ---------------------------------------------------------------------------
273-
# NAVGEM (recent — NOMADS)
274-
# ---------------------------------------------------------------------------
275-
276-
277-
class NavgemNOMADS(HerbieModel):
278-
"""
279-
Navy Global Environment Model (NAVGEM) — recent data from NOMADS.
280-
281-
Approximately last two days available.
282-
283-
Parameters
284-
----------
285-
date : str or datetime
286-
Model initialization datetime (UTC).
287-
step : int, default 0
288-
Forecast lead time in hours (0–168).
289-
290-
References
291-
----------
292-
* https://www.nrlmry.navy.mil/metoc/nogaps/navgem.html
293-
"""
294-
295-
MODEL_NAME = "NavgemNOMADS"
296-
MODEL_DESCRIPTION = "Navy Global Environment Model — NOMADS (recent)"
297-
MODEL_WEBSITES = {
298-
"NOMADS": "https://nomads.ncep.noaa.gov/pub/data/nccf/com/fnmoc/prod/",
299-
}
300-
301-
PARAMS = {}
302-
303-
def _build_sources(self) -> dict:
304-
d = self.date
305-
step = self.step
306-
path = f"navgem.{d:%Y%m%d}/navgem_{d:%Y%m%d%H}f{step:03d}.grib2"
307-
return {
308-
"nomads": GribSource(
309-
f"https://nomads.ncep.noaa.gov/pub/data/nccf/com/fnmoc/prod/{path}",
310-
[".idx"],
311-
),
312-
}
313-
314-
315-
# ---------------------------------------------------------------------------
316-
# NAVGEM / NOGAPS historical — GODAE server
317-
# ---------------------------------------------------------------------------
318-
319-
320-
class NavgemGODAE(HerbieModel):
321-
"""
322-
NAVGEM (2013–2024) and NOGAPS (2004–2013) historical archive on GODAE.
323-
324-
Uses GRIB1 for NOGAPS and GRIB2 for NAVGEM. Variable selection uses
325-
wgrib2-style shorthand that is mapped to GODAE filename components.
326-
327-
Parameters
328-
----------
329-
date : str or datetime
330-
Model initialization datetime (UTC).
331-
step : int, default 0
332-
Forecast lead time in hours.
333-
variable : str
334-
Field to retrieve, in wgrib2-style format: ``'VARNAME:LEVEL'``.
335-
Examples: ``'TMP:500 mb'``, ``'UGRD:10 m'``, ``'HGT:surface'``.
336-
product : {'GMET', 'GLND', 'GOCN'}, default 'GMET'
337-
Product category.
338-
339-
References
340-
----------
341-
* https://usgodae.org/
342-
* https://usgodae.org/docs/layout/mdllayout.pns.html
343-
"""
344-
345-
MODEL_NAME = "NavgemGODAE"
346-
MODEL_DESCRIPTION = "NAVGEM / NOGAPS Historical — GODAE Archive"
347-
MODEL_WEBSITES = {
348-
"GODAE": "https://usgodae.org/",
349-
"Filename guide": "https://usgodae.org/docs/layout/mdllayout.pns.html",
350-
}
351-
352-
PARAMS = {
353-
"product": {
354-
"default": "GMET",
355-
"valid": ["GMET", "GLND", "GOCN", "GCOM"],
356-
"descriptions": {
357-
"GMET": "Meteorological fields",
358-
"GLND": "Land / terrain fields",
359-
"GOCN": "Ocean fields",
360-
"GCOM": "Composition fields",
361-
},
362-
},
363-
"variable": {
364-
"default": "TMP:500 mb",
365-
},
366-
}
367-
368-
# wgrib2 variable name → GODAE filename variable component
369-
_VAR_MAP = {
370-
"TMP": "air_temp",
371-
"DEPR": "dwpt_dprs",
372-
"ABSV": "abs_vort",
373-
"RH": "rltv_hum",
374-
"PRES": "pres",
375-
"UGRD": "wnd_ucmp",
376-
"VGRD": "wnd_vcmp",
377-
"HGT": "geop_ht",
378-
"VAPP": "vpr_pres",
379-
"VVEL": "wnd_vert_vel",
380-
"CAPE": "cape",
381-
"VIS": "visib",
382-
"PWAT": "prcp_h20",
383-
"PRATE": "rain_rate",
384-
"SHTFL": "snsb_heat_flux",
385-
"SNOD": "snw_dpth",
386-
"NSWRS": "sol_rad",
387-
"UFLX": "wnd_strs_ucmp",
388-
"VFLX": "wnd_strs_vcmp",
389-
"PRMSL": "pres_msl",
390-
}
391-
392-
def _parse_variable(self) -> tuple[str, str]:
393-
"""Return (godae_variable, godae_level) from the wgrib2-style variable string."""
394-
raw = self.params.get("variable", "TMP:500 mb")
395-
if ":" in raw:
396-
var, lev = raw.split(":", 1)
397-
else:
398-
var, lev = raw, "surface"
399-
400-
godae_var = self._VAR_MAP.get(var.upper(), var.lower())
401-
402-
if var.upper() == "HGT" and lev == "surface":
403-
return "terr_ht", "0001_000000-000000"
404-
405-
if var.upper() in {"MSLMA", "PRMSL"}:
406-
return godae_var, "0102_000000-000000"
407-
408-
lev = lev.strip()
409-
if lev.endswith("mb"):
410-
mb = int(lev.replace("mb", "").strip())
411-
return godae_var, f"0100_{mb:06d}-000000"
412-
if lev == "2 m":
413-
return godae_var, "0105_000020-000000"
414-
if lev == "10 m":
415-
return godae_var, "0105_000100-000000"
416-
if lev in {"surface", "sfc"}:
417-
return godae_var, "0001_000000-000000"
418-
if lev == "tropopause":
419-
return godae_var, "0007_000000-000000"
420-
421-
return godae_var, "0001_000000-000000"
422-
423-
def _build_sources(self) -> dict:
424-
d = self.date
425-
step = self.step
426-
product = self.params["product"]
427-
godae_var, godae_level = self._parse_variable()
428-
429-
navgem_url = (
430-
f"https://usgodae.org/ftp/outgoing/fnmoc/models/navgem_0.5/"
431-
f"{d:%Y/%Y%m%d%H}/"
432-
f"US058{product}-GR1mdl.0018_0056_{step:03d}00F0RL"
433-
f"{d:%Y%m%d%H}_{godae_level}{godae_var}"
434-
)
435-
navgem_gr2 = (
436-
navgem_url.replace("GR1mdl", "GR2mdl").replace("0018_0056", "0018_0056")
437-
+ ".gr2"
438-
)
439-
nogaps_url = (
440-
f"https://usgodae.org/ftp/outgoing/fnmoc/models/nogaps/"
441-
f"{d:%Y/%Y%m%d%H}/"
442-
f"US058{product}-GR1mdl.0058_0240_{step:03d}00F0RL"
443-
f"{d:%Y%m%d%H}_{godae_level}{godae_var}"
444-
)
445-
446-
return {
447-
"navgem": GribSource(navgem_url, [".idx"]),
448-
"navgem_grib2": GribSource(navgem_gr2, [".idx"]),
449-
"nogaps": GribSource(nogaps_url, [".idx"]),
450-
}

0 commit comments

Comments
 (0)