nos-utils
Python forcing generators for NOAA NOS-OFS ocean forecast systems.
nos-utils is a standalone Python package that replaces the legacy Fortran
and shell preprocessing toolchain (COMF/STOFS) with a modular, testable
pipeline for generating atmospheric, ocean-boundary, river, and tidal forcing
files for SCHISM-based Operational
Forecast Systems (OFS).
Supported systems
SECOFS – SE Coastal Ocean Forecast System. Production-ready on WCOSS2: validated against the operational COMF Fortran pipeline (SSH RMSE = 0.5 mm, R = 0.999998; prep time ~23 min vs 40 min sequential).
STOFS-3D-ATL – Storm Surge 3-D Atlantic. Work in progress: atmospheric, NWM medium-range river, ADT satellite SSH blending, and interior T/S nudging are wired up; operational validation ongoing.
UFS-Coastal variants – DATM-coupled (
nws=4) configurations of both SECOFS and STOFS-3D-ATL (ESMF mesh + HRRR/GFS Delaunay blender).Ensemble – GEFS-driven perturbation members via
ForcingConfig.for_ensemble().
Key features
Byte-identical COMF output structure –
obc.tar(6 files),sflux_*.nc,bctides.in,param.nml,vsource.th, andsource_sink.inmatch the layout expected by the operational model.Precomputed INTERP_REMESH weights – The Fortran triangulation is exported once and replayed every cycle as pure NumPy gather operations, giving Fortran-equivalent accuracy (SSH RMSE 0.5 mm) at a fraction of the runtime.
ROI subsetting for RTOFS – 3D temperature and salinity reads are restricted to the SECOFS subdomain, yielding ~92% I/O reduction.
Parallel Phase 1 prep – GFS, HRRR, NWM, and tidal processors run concurrently via
ThreadPoolExecutor; heavy NetCDF+Delaunay work for RTOFS and nudging runs sequentially in Phase 2.Full-cycle speedup – Total SECOFS prep: ~23 min with nos-utils vs ~40 min for the sequential COMF Fortran pipeline (1.7x faster).
Interior T/S nudging – Python generates
TEM_nu.ncandSAL_nu.ncfor all 32,613 SECOFS interior nodes using precomputed nudge weights.Unified API across OFS – the same
PrepOrchestratorruns SECOFS or STOFS just by swapping theForcingConfigfactory.NCO environment bridge –
nco_bridge.run_prep()reads standardPDY/cyc/COMINgfs/FIXofsvariables and drives the orchestrator from inside a J-job.206 unit tests passing – all inputs are synthetic fixtures; no data downloads required.
Quick start
pip install -e ".[full]"
from nos_utils.config import ForcingConfig
from nos_utils.orchestrator import PrepOrchestrator
config = ForcingConfig.for_secofs(pdy="20260406", cyc=0)
paths = {
"gfs": "/lfs/h1/ops/prod/com/gfs/v16.3",
"hrrr": "/lfs/h1/ops/prod/com/hrrr/v4.1",
"rtofs": "/lfs/h1/ops/prod/com/rtofs/v2.5",
"nwm": "/lfs/h1/ops/prod/com/nwm/v3.0",
"fix": "/path/to/fix/secofs",
"output": "/tmp/secofs_prep",
}
result = PrepOrchestrator(config, paths).run(phase="nowcast")
print(result.summary())
CLI:
nos-utils prep --ofs secofs --pdy 20260406 --cyc 0 \
--gfs /data/gfs --hrrr /data/hrrr --rtofs /data/rtofs \
--nwm /data/nwm --fix /data/fix/secofs --output /work/prep/
nos-utils list # show available OFS factories and processors
Documentation contents
Contents