forcingkit 0.2.0__tar.gz → 0.4.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.
Files changed (100) hide show
  1. {forcingkit-0.2.0 → forcingkit-0.4.0}/.agents/forcingkit.md +4 -4
  2. {forcingkit-0.2.0 → forcingkit-0.4.0}/.env.template +3 -4
  3. {forcingkit-0.2.0 → forcingkit-0.4.0}/AGENTS.md +4 -3
  4. {forcingkit-0.2.0 → forcingkit-0.4.0}/PKG-INFO +9 -6
  5. {forcingkit-0.2.0 → forcingkit-0.4.0}/README.md +8 -5
  6. forcingkit-0.4.0/docs/source/_static/custom.css +24 -0
  7. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/source/atmospheric_forcing.rst +64 -30
  8. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/source/conf.py +2 -1
  9. forcingkit-0.4.0/docs/source/fetchers.rst +200 -0
  10. forcingkit-0.4.0/docs/source/hycom.rst +293 -0
  11. forcingkit-0.4.0/docs/source/index.rst +163 -0
  12. forcingkit-0.4.0/docs/source/necofs.rst +303 -0
  13. forcingkit-0.4.0/docs/source/nyofs.rst +329 -0
  14. forcingkit-0.4.0/docs/source/roadmap.rst +327 -0
  15. forcingkit-0.4.0/docs/source/sources.rst +117 -0
  16. {forcingkit-0.2.0 → forcingkit-0.4.0}/pyproject.toml +1 -1
  17. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/main.py +60 -3
  18. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/routers/removed.py +3 -3
  19. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/dispatcher.py +50 -3
  20. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/dbofs.py +139 -167
  21. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/erddap.py +3 -2
  22. forcingkit-0.4.0/src/forcingkit/fetchers/hycom.py +351 -0
  23. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/necofs.py +2 -1
  24. forcingkit-0.4.0/src/forcingkit/fetchers/noaa.py +245 -0
  25. forcingkit-0.4.0/src/forcingkit/fetchers/nyofs.py +366 -0
  26. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/settings.py +2 -3
  27. forcingkit-0.2.0/tests/integration/test_obc_mab.py → forcingkit-0.4.0/tests/integration/test_obc_offshore_nj.py +4 -4
  28. forcingkit-0.4.0/tests/integration/test_ofs_archive_paths.py +73 -0
  29. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/scripts/inspect_dem.py +12 -5
  30. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_dbofs.py +119 -43
  31. forcingkit-0.4.0/tests/unit/test_hycom.py +368 -0
  32. forcingkit-0.4.0/tests/unit/test_noaa_currents.py +172 -0
  33. forcingkit-0.4.0/tests/unit/test_nyofs.py +417 -0
  34. forcingkit-0.4.0/tests/unit/test_obc_donor_report.py +53 -0
  35. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_settings.py +4 -7
  36. {forcingkit-0.2.0 → forcingkit-0.4.0}/uv.lock +1 -1
  37. forcingkit-0.2.0/docs/source/fetchers.rst +0 -29
  38. forcingkit-0.2.0/docs/source/index.rst +0 -16
  39. forcingkit-0.2.0/docs/source/nyofs.rst +0 -188
  40. forcingkit-0.2.0/docs/source/removed_endpoints.rst +0 -44
  41. forcingkit-0.2.0/src/forcingkit/fetchers/hycom.py +0 -159
  42. forcingkit-0.2.0/src/forcingkit/fetchers/noaa.py +0 -104
  43. forcingkit-0.2.0/src/forcingkit/fetchers/nyofs.py +0 -458
  44. forcingkit-0.2.0/tests/unit/test_hycom.py +0 -32
  45. forcingkit-0.2.0/tests/unit/test_nyofs.py +0 -294
  46. {forcingkit-0.2.0 → forcingkit-0.4.0}/.claude/CLAUDE.md +0 -0
  47. {forcingkit-0.2.0 → forcingkit-0.4.0}/.github/copilot-instructions.md +0 -0
  48. {forcingkit-0.2.0 → forcingkit-0.4.0}/.github/workflows/docs.yml +0 -0
  49. {forcingkit-0.2.0 → forcingkit-0.4.0}/.github/workflows/publish.yml +0 -0
  50. {forcingkit-0.2.0 → forcingkit-0.4.0}/.github/workflows/tests.yml +0 -0
  51. {forcingkit-0.2.0 → forcingkit-0.4.0}/.gitignore +0 -0
  52. {forcingkit-0.2.0 → forcingkit-0.4.0}/.markdownlint.yaml +0 -0
  53. {forcingkit-0.2.0 → forcingkit-0.4.0}/.pre-commit-config.yaml +0 -0
  54. {forcingkit-0.2.0 → forcingkit-0.4.0}/.python-version +0 -0
  55. {forcingkit-0.2.0 → forcingkit-0.4.0}/CONTRIBUTING.md +0 -0
  56. {forcingkit-0.2.0 → forcingkit-0.4.0}/Dockerfile +0 -0
  57. {forcingkit-0.2.0 → forcingkit-0.4.0}/LICENSE +0 -0
  58. {forcingkit-0.2.0 → forcingkit-0.4.0}/docker-compose.yml +0 -0
  59. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/Makefile +0 -0
  60. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/make.bat +0 -0
  61. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/requirements-docs.txt +0 -0
  62. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/source/_extra/CNAME +0 -0
  63. {forcingkit-0.2.0 → forcingkit-0.4.0}/docs/source/_static/forcingkit-noreaster-wind.gif +0 -0
  64. {forcingkit-0.2.0 → forcingkit-0.4.0}/main.py +0 -0
  65. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/__init__.py +0 -0
  66. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/__init__.py +0 -0
  67. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/routers/bathymetry.py +0 -0
  68. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/routers/plotly_api.py +0 -0
  69. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/forcingkit_serve/routers/viewer.py +0 -0
  70. {forcingkit-0.2.0 → forcingkit-0.4.0}/service/run_server.py +0 -0
  71. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/__init__.py +0 -0
  72. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/hrrr.py +0 -0
  73. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/hrrr_atmosphere.py +0 -0
  74. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/hydrography.py +0 -0
  75. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/fetchers/ndbc.py +0 -0
  76. {forcingkit-0.2.0 → forcingkit-0.4.0}/src/forcingkit/zarr_stream.py +0 -0
  77. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/app.js +0 -0
  78. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/favicon.ico +0 -0
  79. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/favicon.svg +0 -0
  80. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/index.html +0 -0
  81. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/logo.svg +0 -0
  82. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/preview3d.js +0 -0
  83. {forcingkit-0.2.0 → forcingkit-0.4.0}/static/styles.css +0 -0
  84. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/__init__.py +0 -0
  85. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/integration/test_auth.py +0 -0
  86. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/integration/test_erddap_fetch.py +0 -0
  87. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/integration/test_nyofs_obc_fetch.py +0 -0
  88. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/integration/test_s3_roms_fetchers.py +0 -0
  89. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/scripts/inspect_grib.py +0 -0
  90. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/scripts/inspect_zarr.py +0 -0
  91. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_dispatcher.py +0 -0
  92. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_hrrr_atm.py +0 -0
  93. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_hrrr_idx.py +0 -0
  94. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_main.py +0 -0
  95. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_ndbc.py +0 -0
  96. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_necofs_parent.py +0 -0
  97. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_noaa_datum.py +0 -0
  98. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_obc_pipeline.py +0 -0
  99. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_removed_routes.py +0 -0
  100. {forcingkit-0.2.0 → forcingkit-0.4.0}/tests/unit/test_zarr_stream.py +0 -0
@@ -3,8 +3,8 @@
3
3
  ## Mission
4
4
 
5
5
  Python microservice providing real-time and historical forcing (the parent ocean and
6
- the HRRR atmosphere) and validation observations to the `coastal-sim` Julia physics
7
- engine.
6
+ the HRRR atmosphere) and validation observations to downstream ocean models, for
7
+ example ones built on Oceananigans.jl or NumericalEarth.
8
8
 
9
9
  ## Environment
10
10
 
@@ -41,7 +41,7 @@ HTTP Request → service/forcingkit_serve/main.py
41
41
  *Note: Because the architecture is modular, a future roadmap item includes the integration of TPXO (via `tpxo.py`) given usage rights.*
42
42
 
43
43
  Atmospheric forcing: HRRR from 2014-07-30 (`hrrr_atmosphere.py`, `/api/v1/atmosphere`).
44
- Earlier runs use ERA5 through NumericalEarth in coastal-sim, not this service.
44
+ Earlier runs use ERA5 through NumericalEarth in the model, not this service.
45
45
 
46
46
  ## Testing
47
47
 
@@ -89,7 +89,7 @@ uv run python -c "from forcingkit.fetchers import nyofs; print(nyofs.get_metadat
89
89
  - **Mocking strategy**: Dispatcher unit tests check tuple/dict return
90
90
  boundaries carefully. When modifying mocked fetchers, track
91
91
  keyword-argument vs positional argument boundaries.
92
- - **Grid normalization**: `coastal-sim` expects elevations positive
92
+ - **Grid normalization**: downstream models expect elevations positive
93
93
  up (LMSL/NAVD88). Normalize any inverted datasets in the fetcher
94
94
  tier before the dispatcher sees them.
95
95
  - **Cache keys**: Cache Zarr keys are deterministic hashes of bbox
@@ -1,13 +1,12 @@
1
1
  # forcingkit environment variables
2
2
  # Copy this file to .env and fill in your credentials.
3
- # This file is loaded by coastal-sim/docker-compose.yml via env_file.
3
+ # A docker-compose service can load it with env_file.
4
4
 
5
5
  # No credentials are required at present: HRRR, NOAA OFS, NECOFS, HYCOM, NDBC and
6
6
  # CO-OPS are all served without authentication.
7
7
 
8
- # Cache root for every store (default ~/.cache/forcingkit). The old names
9
- # ECODATA_CACHE_CACHE_DIR and COASTAL_SIM_DATA_CACHE_DIR are still read, with a
10
- # warning, until the next release.
8
+ # Cache root for every store (default ~/.cache/forcingkit). The old name
9
+ # ECODATA_CACHE_CACHE_DIR is still read, with a warning, until the next release.
11
10
  # FORCINGKIT_CACHE_DIR=~/.cache/forcingkit
12
11
 
13
12
  # Threads for parallel OPeNDAP reads (default 4; was ECODATA_CACHE_MAX_WORKERS).
@@ -22,9 +22,10 @@ guidance in this repository.
22
22
  ## Repository Focus
23
23
 
24
24
  forcingkit is a Python microservice that fetches, harmonizes, regrids, and serves
25
- real-time and historical forcing to the `coastal-sim` Julia physics engine: the parent
26
- ocean (`/api/v1/obc`, schema z-v2), the HRRR atmosphere (`/api/v1/atmosphere`), tides,
27
- and station telemetry and NDBC observations for validation.
25
+ real-time and historical forcing to downstream ocean models (for example ones built on
26
+ Oceananigans.jl or NumericalEarth): the parent ocean (`/api/v1/obc`, schema z-v3), the
27
+ HRRR atmosphere (`/api/v1/atmosphere`), tides, and station telemetry and NDBC
28
+ observations for validation.
28
29
 
29
30
  ## Core Rules
30
31
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: forcingkit
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Spatiotemporal forcing for computational Earth-system models: selects, regrids and serves model-ready time series with provenance.
5
5
  Project-URL: Documentation, https://forcingkit.docs.lhzn.io
6
6
  Project-URL: Issues, https://github.com/lhzn-io/forcingkit/issues
@@ -255,7 +255,7 @@ Spatiotemporal forcing for computational Earth-system models: selects, regrids a
255
255
 
256
256
  `forcingkit` sits between operational and archive data providers (NOAA HRRR, NECOFS, NOAA OFS, HYCOM, NDBC, CO-OPS) and model codes such as `Oceananigans.jl`. It delivers a model's parent ocean on true z levels (`/api/v1/obc`) and its HRRR surface atmosphere on a regular grid (`/api/v1/atmosphere`), plus station observations for validation, as schema-versioned Zarr stores that record their sources.
257
257
 
258
- forcingkit was named ecodata-cache until 2026-10-05; GitHub redirects the old repository URLs. The Python package is `forcingkit` (was `ecodata_cache`), and environment variables use the `FORCINGKIT_` prefix; the old names are still read, with a warning, until the next release. Documentation: <https://forcingkit.docs.lhzn.io>, including the [routes removed on the same date](https://forcingkit.docs.lhzn.io/removed_endpoints.html).
258
+ Documentation: <https://forcingkit.docs.lhzn.io>.
259
259
 
260
260
  ## Goals
261
261
 
@@ -273,14 +273,17 @@ The primary goal of forcingkit is to provide clean, standardized ocean and atmos
273
273
 
274
274
  ## Current Coverage
275
275
 
276
- - **Oceanic Forcing**: NYOFS, NECOFS, DBOFS, HYCOM (Operational & Historical).
276
+ - **Oceanic Forcing**: NYOFS, NECOFS, DBOFS, HYCOM (global, 1994 to present).
277
277
  - **Atmospheric Forcing**: HRRR (3 km, hourly, 2014-07-30 to present), regridded to 0.03 degrees.
278
278
 
279
279
  ## Roadmap
280
280
 
281
- - **Enhanced IOOS Coverage**: Expanding our data fetchers to support more regional nodes across the West Coast (WCOFS) and Gulf of Mexico (NGOFS2).
282
- - **Improved Caching Policies**: Implementing dynamic cache invalidation based on NOAA operational forecast updates to ensure realtime predictions stay synchronized.
283
- - **Variable Expansions**: Providing native spatiotemporal transformations for wave spectra and biogeochemical tracers.
281
+ - **Coverage first**: a second global parent (Copernicus GLO12, GLORYS12 for 1993 on, NOAA RTOFS), the remaining NOAA forecast systems (West Coast, Gulf, Chesapeake, Great Lakes, Alaska), the Doppio reanalysis for 2007 to 2024 in the Northeast, HRRR Alaska and ECMWF IFS for the atmosphere, and a first European ocean source from Copernicus Marine (IBI or the North West Shelf).
282
+ - **Resolution second**: the NYOFS fine grid, the Monterey Bay nests of WCOFS, and SFBOFS inside San Francisco Bay.
283
+ - **NYOFS and DBOFS as z-v3 parents**: both on true depths with geographic axes.
284
+ - **Forecast mode and cache policy**: HRRR forecast cycles, and invalidation of forecast-built stores when a newer cycle is published.
285
+
286
+ The full list, with what each candidate offers, is at <https://forcingkit.docs.lhzn.io/roadmap.html>. Contributions are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md).
284
287
 
285
288
  ## Architecture overview
286
289
 
@@ -14,7 +14,7 @@ Spatiotemporal forcing for computational Earth-system models: selects, regrids a
14
14
 
15
15
  `forcingkit` sits between operational and archive data providers (NOAA HRRR, NECOFS, NOAA OFS, HYCOM, NDBC, CO-OPS) and model codes such as `Oceananigans.jl`. It delivers a model's parent ocean on true z levels (`/api/v1/obc`) and its HRRR surface atmosphere on a regular grid (`/api/v1/atmosphere`), plus station observations for validation, as schema-versioned Zarr stores that record their sources.
16
16
 
17
- forcingkit was named ecodata-cache until 2026-10-05; GitHub redirects the old repository URLs. The Python package is `forcingkit` (was `ecodata_cache`), and environment variables use the `FORCINGKIT_` prefix; the old names are still read, with a warning, until the next release. Documentation: <https://forcingkit.docs.lhzn.io>, including the [routes removed on the same date](https://forcingkit.docs.lhzn.io/removed_endpoints.html).
17
+ Documentation: <https://forcingkit.docs.lhzn.io>.
18
18
 
19
19
  ## Goals
20
20
 
@@ -32,14 +32,17 @@ The primary goal of forcingkit is to provide clean, standardized ocean and atmos
32
32
 
33
33
  ## Current Coverage
34
34
 
35
- - **Oceanic Forcing**: NYOFS, NECOFS, DBOFS, HYCOM (Operational & Historical).
35
+ - **Oceanic Forcing**: NYOFS, NECOFS, DBOFS, HYCOM (global, 1994 to present).
36
36
  - **Atmospheric Forcing**: HRRR (3 km, hourly, 2014-07-30 to present), regridded to 0.03 degrees.
37
37
 
38
38
  ## Roadmap
39
39
 
40
- - **Enhanced IOOS Coverage**: Expanding our data fetchers to support more regional nodes across the West Coast (WCOFS) and Gulf of Mexico (NGOFS2).
41
- - **Improved Caching Policies**: Implementing dynamic cache invalidation based on NOAA operational forecast updates to ensure realtime predictions stay synchronized.
42
- - **Variable Expansions**: Providing native spatiotemporal transformations for wave spectra and biogeochemical tracers.
40
+ - **Coverage first**: a second global parent (Copernicus GLO12, GLORYS12 for 1993 on, NOAA RTOFS), the remaining NOAA forecast systems (West Coast, Gulf, Chesapeake, Great Lakes, Alaska), the Doppio reanalysis for 2007 to 2024 in the Northeast, HRRR Alaska and ECMWF IFS for the atmosphere, and a first European ocean source from Copernicus Marine (IBI or the North West Shelf).
41
+ - **Resolution second**: the NYOFS fine grid, the Monterey Bay nests of WCOFS, and SFBOFS inside San Francisco Bay.
42
+ - **NYOFS and DBOFS as z-v3 parents**: both on true depths with geographic axes.
43
+ - **Forecast mode and cache policy**: HRRR forecast cycles, and invalidation of forecast-built stores when a newer cycle is published.
44
+
45
+ The full list, with what each candidate offers, is at <https://forcingkit.docs.lhzn.io/roadmap.html>. Contributions are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md).
43
46
 
44
47
  ## Architecture overview
45
48
 
@@ -0,0 +1,24 @@
1
+ /* Use more of a wide screen: the theme caps the content column at 800 px. */
2
+ .wy-nav-content {
3
+ max-width: 1200px;
4
+ }
5
+
6
+ /* Let table cells wrap instead of forcing a horizontal scrollbar. The theme sets nowrap on
7
+ every cell and puts tables in a scrolling container. */
8
+ .wy-table-responsive table td,
9
+ .wy-table-responsive table th {
10
+ white-space: normal;
11
+ }
12
+
13
+ /* On wide screens wrapped tables fit, so drop the scroll container; on phones keep it, so a
14
+ table too wide even when wrapped scrolls rather than being clipped. */
15
+ @media screen and (min-width: 768px) {
16
+ .wy-table-responsive {
17
+ overflow-x: visible;
18
+ }
19
+ }
20
+
21
+ /* Keep long code spans (archive paths, URLs) from widening a column past the page. */
22
+ .wy-table-responsive table td code {
23
+ overflow-wrap: anywhere;
24
+ }
@@ -2,7 +2,8 @@ Atmospheric Forcing Datasets
2
2
  ============================
3
3
 
4
4
  As of 2026-10-04. Which atmospheric datasets can force a coastal ocean model through this service
5
- or through NumericalEarth, how they compare, and which one the CoastalSim configurations use.
5
+ or through `NumericalEarth <https://github.com/NumericalEarth/NumericalEarth.jl>`__, how they
6
+ compare, and which to choose.
6
7
 
7
8
  An ocean model's surface fluxes need, at every hour of the run: 10 m wind (eastward and
8
9
  northward), 2 m air temperature and specific humidity, surface pressure, precipitation, and
@@ -23,22 +24,23 @@ Summary
23
24
  - Output step
24
25
  - Coverage
25
26
  - Latency
26
- - Path in our stack
27
- * - **HRRR** (NOAA NCEP)
27
+ - Path to a model
28
+ * - **HRRR** (`NOAA GSL <https://gsl.noaa.gov/>`__, `NCEP <https://www.nco.ncep.noaa.gov/>`__)
28
29
  - Hourly-cycling forecast, 3 km convection-allowing, radar assimilation
29
30
  - 3 km, Lambert conformal over CONUS
30
31
  - 1 h (15 min for some fields)
31
32
  - CONUS; archive on AWS from 2014-07-30
32
33
  - About an hour after each cycle
33
- - **forcingkit** ``/api/v1/atmosphere`` (schema ``hrrr-atm-v1``); default for CoastalSim
34
- * - **ERA5** (ECMWF, Copernicus C3S)
34
+ - **forcingkit** ``/api/v1/atmosphere`` (schema ``hrrr-atm-v1``); the default
35
+ * - **ERA5** (`ECMWF <https://www.ecmwf.int/>`__, `Copernicus C3S
36
+ <https://climate.copernicus.eu/>`__)
35
37
  - Global reanalysis (4D-Var)
36
38
  - 0.25 degrees (about 31 km)
37
39
  - 1 h
38
40
  - 1940 to present
39
41
  - ERA5T about 5 days; final ERA5 2 to 3 months
40
- - **NumericalEarth** ``ERA5PrescribedAtmosphere`` (coastal-sim ``atmosphere = "era5"``)
41
- * - **RRFS v1** (NOAA NCEP)
42
+ - **NumericalEarth** ``ERA5PrescribedAtmosphere``
43
+ * - **RRFS v1** (`NOAA GSL <https://gsl.noaa.gov/rrfs/>`__, NCEP)
42
44
  - Hourly-cycling forecast, FV3 limited-area, 3 km
43
45
  - 3 km, North America
44
46
  - 1 h
@@ -52,28 +54,29 @@ Summary
52
54
  - Retired 2026-10-06 in favour of RRFS
53
55
  - Four cycles a day, to 60 h
54
56
  - Not integrated; do not adopt
55
- * - **GFS** (NOAA NCEP)
57
+ * - **GFS** (`NOAA NCEP
58
+ <https://www.emc.ncep.noaa.gov/emc/pages/numerical_forecast_systems/gfs.php>`__)
56
59
  - Global forecast, FV3
57
60
  - 0.25 degrees
58
61
  - 1 h to 120 h, then 3 h
59
62
  - Global; NODD archive on AWS
60
63
  - Four cycles a day, to 384 h
61
64
  - Not integrated; the natural extension past HRRR's 48 h in forecast mode
62
- * - **ECMWF IFS open data**
65
+ * - **ECMWF IFS** `open data <https://www.ecmwf.int/en/forecasts/datasets/open-data>`__
63
66
  - Global forecast
64
67
  - 0.25 degrees
65
68
  - 3 h, then 6 h
66
69
  - Global; real time
67
70
  - Four cycles a day, to 15 days (00 and 12 UTC)
68
71
  - Not integrated; CC-BY-4.0 since 2025-10-01
69
- * - **JRA55-do** (JMA, MRI)
72
+ * - **JRA55-do** (JMA, `MRI <https://www.mri-jma.go.jp/index_en.html>`__)
70
73
  - Reanalysis adjusted for ocean-sea-ice models
71
74
  - About 0.5 degrees
72
75
  - 3 h
73
76
  - 1958-01-01 to 2024-02-01, final version 1.6.0
74
77
  - Discontinued (JRA-55 ended January 2024; successor JRA-3Q)
75
78
  - **NumericalEarth** ``JRA55PrescribedAtmosphere`` (its catalogue ends 2019-12-31)
76
- * - **ECCO v4** (NASA JPL)
79
+ * - **ECCO v4** (`ECCO Consortium <https://ecco-group.org/>`__, NASA JPL)
77
80
  - Ocean state estimate's adjusted forcing
78
81
  - About 1 degree
79
82
  - Monthly
@@ -87,9 +90,13 @@ Datasets in use
87
90
  HRRR (default)
88
91
  ~~~~~~~~~~~~~~
89
92
 
90
- *Provenance.* NOAA NCEP's High-Resolution Rapid Refresh, version 4, a 3 km convection-allowing
91
- model that assimilates radar every 15 minutes and starts a new forecast every hour. Distributed
92
- through the NOAA Open Data Dissemination programme in the ``noaa-hrrr-bdp-pds`` bucket on AWS
93
+ *Provenance.* NOAA's `High-Resolution Rapid Refresh <https://rapidrefresh.noaa.gov/hrrr/>`__,
94
+ version 4, developed by the NOAA Global Systems Laboratory and run by NCEP: a 3 km
95
+ convection-allowing model that assimilates radar every 15 minutes and starts a new forecast every
96
+ hour (`Dowell et al., 2022 <https://doi.org/10.1175/WAF-D-21-0151.1>`__; `James et al., 2022
97
+ <https://doi.org/10.1175/WAF-D-21-0130.1>`__). Distributed through the `NOAA Open Data
98
+ Dissemination <https://www.noaa.gov/information-technology/open-data-dissemination>`__ programme
99
+ in the `noaa-hrrr-bdp-pds <https://registry.opendata.aws/noaa-hrrr-pds/>`__ bucket on AWS
93
100
  (us-east-1), anonymous, from 2014-07-30 to the present. NOAA open data: free to use; NOAA asks
94
101
  for attribution and that modified products not be presented as NOAA's.
95
102
 
@@ -134,8 +141,8 @@ atmosphere regridder accepts. Records run from one hour before the run start to
134
141
  end; a missing message or hour raises, and the store is published only when complete. Building
135
142
  one hour takes about 6.5 s on a warm connection, so a 168 h window takes about 19 minutes.
136
143
 
137
- *Strengths.* Resolves the land-sea contrast, sea breezes and frontal timing at the scale of our
138
- domains (MAB is 15 by 17 km; LIS 85 by 65 km). Hourly radiation and precipitation. No credentials.
144
+ *Strengths.* Resolves the land-sea contrast, sea breezes and frontal timing at the scale of
145
+ coastal domains from about 15 to 85 km across. Hourly radiation and precipitation. No credentials.
139
146
 
140
147
  *Limits.* CONUS only. A forecast product, not a reanalysis: it carries forecast-model biases and is
141
148
  not homogeneous across HRRR versions (v4 since December 2020). Radiation is instantaneous.
@@ -143,24 +150,28 @@ not homogeneous across HRRR versions (v4 since December 2020). Radiation is inst
143
150
  ERA5 (fallback)
144
151
  ~~~~~~~~~~~~~~~
145
152
 
146
- *Provenance.* ECMWF's fifth-generation global reanalysis for the Copernicus Climate Change
147
- Service: 0.25 degree grid (about 31 km), hourly, 1940 to the present. ERA5T, the initial release,
153
+ *Provenance.* `ECMWF <https://www.ecmwf.int/>`__'s fifth-generation global reanalysis for the
154
+ `Copernicus Climate Change Service <https://climate.copernicus.eu/>`__ (`Hersbach et al., 2020
155
+ <https://doi.org/10.1002/qj.3803>`__): 0.25 degree grid (about 31 km), hourly, 1940 to the present.
156
+ ERA5T, the initial release,
148
157
  appears about five days behind real time and is overwritten by the final ERA5 two to three months
149
- later. Requires a free Copernicus Climate Data Store account (credentials in ``~/.cdsapirc``);
158
+ later. Requires a free `Copernicus Climate Data Store <https://cds.climate.copernicus.eu/>`__
159
+ account (credentials in ``~/.cdsapirc``);
150
160
  Copernicus licence, attribution required.
151
161
 
152
- *How it is used.* CoastalSim reads it through NumericalEarth's ``ERA5PrescribedAtmosphere`` and
153
- ``ERA5PrescribedRadiation`` over the bbox padded by 0.5 degrees, with linear time indexing and one
154
- hour of padding past the end. Accumulated fields (precipitation, radiation) are hour-ending means
155
- that NumericalEarth places at the centre of their hour. NumericalEarth 0.8.1's catalogue stops at
156
- 2025-12-31; coastal-sim extends it to six days before today until upstream rolls the date.
162
+ *How it is used.* A model reads it through NumericalEarth's ``ERA5PrescribedAtmosphere`` and
163
+ ``ERA5PrescribedRadiation``, for example over the bbox padded by 0.5 degrees, with linear time
164
+ indexing and one hour of padding past the end. Accumulated fields (precipitation, radiation) are
165
+ hour-ending means that NumericalEarth places at the centre of their hour. NumericalEarth 0.8.1's
166
+ catalogue stops at 2025-12-31; later dates need the catalogue extended until upstream rolls it.
157
167
 
158
168
  *Strengths.* Homogeneous, global, long, assimilates far more observations than any forecast; the
159
169
  standard against which forcing biases are judged.
160
170
 
161
- *Limits.* At 31 km a domain like MAB spans one or two ERA5 cells, so the forcing is nearly uniform
162
- and smears the coast: in the first hours of 2026-04-02 over MAB, the ERA5 box (which includes New
163
- Jersey land) was about 3 K warmer at 2 m and had about half HRRR's wind speed. Latency rules out
171
+ *Limits.* At 31 km a 15 km coastal domain spans one or two ERA5 cells, so the forcing is nearly
172
+ uniform and smears the coast: in the first hours of 2026-04-02 over such a domain off New Jersey,
173
+ the ERA5 box (which includes New Jersey land) was about 3 K warmer at 2 m and had about half HRRR's
174
+ wind speed. Latency rules out
164
175
  anything closer than five days to the present.
165
176
 
166
177
  Choosing
@@ -177,20 +188,43 @@ Choosing
177
188
  * - Hindcast before 2014-07-30, outside CONUS, or a reanalysis-grade comparison run
178
189
  - ERA5
179
190
  * - Forecast to 48 h
180
- - HRRR forecast mode (planned, Sprint 4): one cycle's f01 to f48 from the 00, 06, 12 or 18 UTC
191
+ - HRRR forecast mode (planned): one cycle's f01 to f48 from the 00, 06, 12 or 18 UTC
181
192
  cycle
182
193
  * - Forecast beyond 48 h
183
194
  - HRRR to 48 h, then GFS or ECMWF IFS open data (not integrated); RRFS to 84 h once it is
184
195
  established in operations
185
196
  * - Multi-decade or climate-scale forcing
186
- - ERA5, or JRA55-do through NumericalEarth (to 2019 in its catalogue)
197
+ - ERA5, or JRA55-do (`Tsujino et al., 2018 <https://doi.org/10.1016/j.ocemod.2018.07.002>`__)
198
+ through NumericalEarth (to 2019 in its catalogue)
187
199
 
188
200
  References
189
201
  ----------
190
202
 
203
+ Citations
204
+ ~~~~~~~~~
205
+
206
+ - Dowell, D. C., C. R. Alexander, E. P. James, et al. (2022). The High-Resolution Rapid Refresh
207
+ (HRRR): An hourly updating convection-allowing forecast model. Part I: Motivation and system
208
+ description. *Weather and Forecasting*, 37(8), 1371-1395.
209
+ `doi:10.1175/WAF-D-21-0151.1 <https://doi.org/10.1175/WAF-D-21-0151.1>`__
210
+ - James, E. P., C. R. Alexander, D. C. Dowell, et al. (2022). The High-Resolution Rapid Refresh
211
+ (HRRR): An hourly updating convection-allowing forecast model. Part II: Forecast performance.
212
+ *Weather and Forecasting*, 37(8), 1397-1417.
213
+ `doi:10.1175/WAF-D-21-0130.1 <https://doi.org/10.1175/WAF-D-21-0130.1>`__
214
+ - Hersbach, H., B. Bell, P. Berrisford, et al. (2020). The ERA5 global reanalysis. *Quarterly
215
+ Journal of the Royal Meteorological Society*, 146(730), 1999-2049.
216
+ `doi:10.1002/qj.3803 <https://doi.org/10.1002/qj.3803>`__
217
+ - Tsujino, H., S. Urakawa, H. Nakano, et al. (2018). JRA-55 based surface dataset for driving
218
+ ocean-sea-ice models (JRA55-do). *Ocean Modelling*, 130, 79-139.
219
+ `doi:10.1016/j.ocemod.2018.07.002 <https://doi.org/10.1016/j.ocemod.2018.07.002>`__
220
+
221
+ Links
222
+ ~~~~~
223
+
191
224
  - NOAA HRRR on AWS: https://registry.opendata.aws/noaa-hrrr-pds/
192
225
  - NOAA RRFS: https://gsl.noaa.gov/rrfs/ ; operational date and retirements:
193
226
  https://gribstream.com/blog/noaa-rrfs-refs-operational-august-2026
194
- - ERA5T latency: https://climate.copernicus.eu/key-update-climate-dataset-brings-data-five-days-behind-real-time
227
+ - ERA5T latency:
228
+ https://climate.copernicus.eu/key-update-climate-dataset-brings-data-five-days-behind-real-time
195
229
  - ECMWF open data: https://www.ecmwf.int/en/forecasts/datasets/open-data
196
230
  - JRA55-do: https://climate.mri-jma.go.jp/pub/ocean/JRA55-do/
@@ -9,7 +9,7 @@ sys.path.insert(0, os.path.abspath("../../src"))
9
9
  project = "forcingkit"
10
10
  copyright = "2026, Long Horizon Observatory"
11
11
  author = "Daniel Fry"
12
- release = "0.2.0"
12
+ release = "0.4.0"
13
13
 
14
14
  extensions = [
15
15
  "sphinx.ext.autodoc",
@@ -26,5 +26,6 @@ language = "en"
26
26
 
27
27
  html_theme = "sphinx_rtd_theme"
28
28
  html_static_path = ["_static"]
29
+ html_css_files = ["custom.css"]
29
30
  # CNAME for the custom domain forcingkit.docs.lhzn.io, copied to the site root.
30
31
  html_extra_path = ["_extra"]
@@ -0,0 +1,200 @@
1
+ Data Fetchers
2
+ =============
3
+
4
+ A fetcher (``forcingkit.fetchers``) talks to one external provider: it resolves where the data
5
+ for a time lives, reads only the subset a request needs, and returns it in a common layout. The
6
+ dispatcher (``forcingkit.dispatcher``) chooses among fetchers, falls back when one cannot deliver,
7
+ and writes the result to the local Zarr cache, so a request is fetched from the provider once.
8
+
9
+ Atmospheric forcing (``/api/v1/atmosphere``)
10
+ --------------------------------------------
11
+
12
+ .. list-table::
13
+ :header-rows: 1
14
+ :widths: 14 86
15
+
16
+ * - Source
17
+ - Notes
18
+ * - **HRRR**
19
+ - NOAA `High-Resolution Rapid Refresh <https://rapidrefresh.noaa.gov/hrrr/>`__ (developed by
20
+ the `NOAA Global Systems Laboratory <https://gsl.noaa.gov/>`__, run operationally by
21
+ `NCEP <https://www.nco.ncep.noaa.gov/>`__), 3 km, from the anonymous AWS S3 bucket
22
+ `noaa-hrrr-bdp-pds <https://registry.opendata.aws/noaa-hrrr-pds/>`__; the archive starts
23
+ 2014-07-30. Surface fields are interpolated to a regular 0.03 degree grid and streamed hour
24
+ by hour (schema ``hrrr-atm-v1``). Earlier dates use `ERA5
25
+ <https://cds.climate.copernicus.eu/>`__ through `NumericalEarth
26
+ <https://github.com/NumericalEarth/NumericalEarth.jl>`__ in the model, outside this
27
+ service. See :doc:`atmospheric_forcing`.
28
+
29
+ Parent ocean (``/api/v1/obc``)
30
+ ------------------------------
31
+
32
+ .. list-table::
33
+ :header-rows: 1
34
+ :widths: 14 86
35
+
36
+ * - Source
37
+ - Notes
38
+ * - **NECOFS**
39
+ - `Northeast Coastal Ocean Forecast System <https://fvcom.smast.umassd.edu/?p=20>`__, `FVCOM
40
+ <https://fvcom.smast.umassd.edu/>`__ GOM7 (`UMass Dartmouth SMAST
41
+ <https://www.umassd.edu/smast/>`__ and `WHOI <https://www.whoi.edu/>`__), unstructured mesh
42
+ with 45 sigma layers. Daily history files from 2025-01-01, then the rolling forecast.
43
+ The only donor that streams the ``z-v3`` parent store. See :doc:`necofs`.
44
+ * - **NYOFS**
45
+ - `NOAA New York/New Jersey Operational Forecast System
46
+ <https://tidesandcurrents.noaa.gov/ofs/nyofs/nyofs.html>`__ (`NOAA CO-OPS
47
+ <https://tidesandcurrents.noaa.gov/>`__), POM on a curvilinear grid with 7
48
+ sigma levels, NY/NJ Harbor. Ranked first inside its domain. 7-day CO-OPS aggregation,
49
+ then the nowcast archive (AWS S3 from 2024-11-19, NCEI from 2014). Legacy output layout
50
+ rather than ``z-v3``. See :doc:`nyofs`.
51
+ * - **DBOFS**
52
+ - `NOAA Delaware Bay Operational Forecast System
53
+ <https://tidesandcurrents.noaa.gov/ofs/dbofs/dbofs.html>`__ (NOAA CO-OPS),
54
+ `ROMS <https://www.myroms.org/>`__, about 100 m, domain
55
+ [-75.875, 37.810, -73.264, 40.206]. 7-day CO-OPS aggregation, then the hourly nowcast
56
+ archive (AWS S3 from 2024-11-19, NCEI from 2014). Legacy output layout.
57
+ * - :doc:`HYCOM <hycom>`
58
+ - `HYCOM <https://www.hycom.org/>`__ (1/12 degree, about 9 km, 40 z levels), global, from
59
+ the `HYCOM consortium data server <https://tds.hycom.org/thredds/catalog.html>`__, 1994 to
60
+ the present. The experiment follows the date: GLBv0.08 ``expt_53.X`` (reanalysis) to
61
+ 2015, a chain of GLBv0.08 analysis experiments to 2018-12-04, GLBy0.08 ``expt_93.0`` to
62
+ 2024-09-05, then ESPC-D-V02. A window that spans a switch is stitched; if any piece fails,
63
+ the whole window fails. Tidal only from 2024-09-05, recorded in the store's ``tides``
64
+ attribute (``"none"``, ``"included"`` or ``"mixed"``). Last-resort fallback; legacy
65
+ output layout.
66
+
67
+ `TPXO10 <https://www.tpxo.net/>`__ tidal harmonics are a roadmap item, not integrated; the
68
+ `pyTMD <https://github.com/pyTMD/pyTMD>`__ dependency was removed on
69
+ 2026-10-05. The ``include_tides`` and ``tidal_model`` request fields
70
+ are still accepted and form part of the cache key, but no tide is added to the parent store.
71
+ A parent that already contains the tide (a HYCOM store with ``tides = "included"``) should not
72
+ have tides added again downstream; see :doc:`hycom`.
73
+
74
+ Donor selection
75
+ ~~~~~~~~~~~~~~~
76
+
77
+ Each parent-ocean fetcher declares a domain box and an approximate resolution. A donor is a
78
+ candidate when it accepts the request box (NYOFS and DBOFS require the box to lie inside their
79
+ domain; NECOFS accepts any overlap; HYCOM accepts everything). Candidates are ranked by **domain
80
+ area first, smallest first**, then by resolution, on the reasoning that the most specialised
81
+ system is the best local one:
82
+
83
+ .. list-table::
84
+ :header-rows: 1
85
+ :widths: 20 30 20 30
86
+
87
+ * - Donor
88
+ - Declared domain (lon/lat)
89
+ - Area (degree squared)
90
+ - Declared resolution
91
+ * - NYOFS
92
+ - [-74.475, 40.389, -73.743, 40.940]
93
+ - 0.40
94
+ - 100 m
95
+ * - DBOFS
96
+ - [-75.875, 37.810, -73.264, 40.206]
97
+ - 6.3
98
+ - 100 m
99
+ * - NECOFS
100
+ - [-77.0, 35.0, -65.0, 46.0]
101
+ - 132
102
+ - 200 m
103
+ * - HYCOM
104
+ - global
105
+ - 64800
106
+ - 9 km
107
+
108
+ The dispatcher tries the candidates in order. A donor that returns nothing or raises is logged
109
+ and skipped unless the request sets ``allow_donor_fallback: false``, in which case the first
110
+ failure is an error. A donor that streams (NECOFS) either completes its store or fails; it never
111
+ publishes a shortened one.
112
+
113
+ Observations
114
+ ------------
115
+
116
+ These serve validation rather than forcing:
117
+
118
+ - **CO-OPS** water level (``/api/v1/tide``), from the `NOAA CO-OPS data API
119
+ <https://api.tidesandcurrents.noaa.gov/api/prod/>`__, with a datum
120
+ fallback to MSL where a station has no NAVD88 datum.
121
+ - **NDBC** buoy meteorology and ADCP profiles (``/api/v1/ndbc``), from the `NOAA National Data
122
+ Buoy Center <https://www.ndbc.noaa.gov/>`__.
123
+ - **UConn ERDDAP** water-column profiles (``/api/v1/telemetry/station`` and ``/bbox``), from the
124
+ `University of Connecticut Department of Marine Sciences <https://marinesciences.uconn.edu/>`__
125
+ `ERDDAP server <http://merlin.dms.uconn.edu:8080/erddap/index.html>`__.
126
+
127
+ NOAA OFS archive locations
128
+ --------------------------
129
+
130
+ As checked on 2026-10-06, NYOFS and DBOFS output is available from three places:
131
+
132
+ .. list-table::
133
+ :header-rows: 1
134
+ :widths: 22 30 48
135
+
136
+ * - Location
137
+ - Span
138
+ - Layout
139
+ * - `CO-OPS THREDDS <https://opendap.co-ops.nos.noaa.gov/thredds/catalog/catalog.html>`__ FMRC
140
+ aggregation
141
+ - Rolling 7 days
142
+ - One virtual OPeNDAP dataset per system
143
+ (``opendap.co-ops.nos.noaa.gov/thredds/dodsC/<OFS>/fmrc/Aggregated_7_day_<OFS>_Fields_Forecast_best.ncd``).
144
+ * - `NOAA NCEI <https://www.ncei.noaa.gov/>`__ THREDDS (`model-nyofs-files
145
+ <https://www.ncei.noaa.gov/thredds/catalog/model-nyofs-files/catalog.html>`__,
146
+ ``model-dbofs-files``)
147
+ - 2014 to the present month, with occasional missing days (NYOFS 2024-06 has 25 of 30)
148
+ - One directory per month, ``{yyyy}/{mm}/``, with every file of the month in it. File names
149
+ changed with the 2024-09-09 cycles (from ``nos.<ofs>.fields.<n|f><hhh>.<yyyymmdd>.t<cc>z.nc``
150
+ and ``nos.nyofs.fields.<nowcast|forecast>.<yyyymmdd>.t<cc>z.nc`` to
151
+ ``<ofs>.t<cc>z.<yyyymmdd>.fields.<...>.nc``).
152
+ * - AWS S3 `noaa-nos-ofs-pds <https://registry.opendata.aws/noaa-ofs/>`__ (`NOAA Open Data
153
+ Dissemination <https://www.noaa.gov/information-technology/open-data-dissemination>`__)
154
+ - 2024 to the present, with gaps before 2024-11-19
155
+ - From 2024-11-19, one directory per day, ``<ofs>/netcdf/{yyyy}/{mm}/{dd}/``; the first day
156
+ holds only its last cycle. Before that, one flat directory per month,
157
+ ``<ofs>/netcdf/{yyyymm}/``, with a mix of file names (NYOFS 2024-07 uses the older names,
158
+ DBOFS 2024-07 the newer ones); several of those months are partial and some are absent
159
+ (NYOFS lacks 2024-01 to 2024-03, 2024-05 and 2024-06; DBOFS lacks 2024-02 and starts
160
+ 2024-01 on the 29th).
161
+
162
+ .. note::
163
+ An earlier version of this page said that NCEI stopped archiving at the end of November 2023,
164
+ that AWS began in January 2024, and that December 2023 was therefore missing. None of that
165
+ holds: NCEI has every day of December 2023 for both NYOFS and DBOFS (124 NYOFS and 744 DBOFS
166
+ field files) and has continued archiving through 2026, while the AWS archive is the one with
167
+ gaps.
168
+
169
+ The NYOFS and DBOFS fetchers read nowcast files only, so a window is a chain of analyses
170
+ rather than forecasts. For each file they try AWS (per-day layout) first when the date is
171
+ 2024-11-19 or later, then NCEI, which covers every date; the flat AWS month directories are
172
+ not used. A window with a file missing from both is not served by that donor, and the
173
+ dispatcher falls back. DBOFS publishes one file per hour: file ``n001`` to ``n006`` of cycle
174
+ ``t<cc>z`` (00, 06, 12, 18 UTC) hold hours ``cc - 5`` to ``cc``. NYOFS publishes one file per
175
+ cycle (05, 11, 17, 23 UTC) holding the same six hours.
176
+
177
+ Both fetchers were corrected on 2026-10-06. Before that, every NYOFS archive date failed (see
178
+ :doc:`nyofs`), and DBOFS sent 2024 dates before 2024-11-19 to an AWS layout that does not
179
+ hold them, took some hours from the wrong file, joined NCEI files along a ``time`` dimension
180
+ they do not have (theirs is ``ocean_time``), and left the ROMS fill value (1e37) in land
181
+ cells read through NCEI.
182
+
183
+ For the AWS layout, see the `NOAA NODD OFS documentation
184
+ <https://github.com/NOAA-Big-Data-Program/nodd-data-docs/blob/main/OFS/README.md>`_ and the
185
+ `Registry of Open Data entry <https://registry.opendata.aws/noaa-ofs/>`_.
186
+
187
+ Common processing
188
+ -----------------
189
+
190
+ - **Hourly time axis.** Non-streaming donors are resampled to a strict hourly index by linear
191
+ interpolation. Streaming donors deliver hourly records directly. HYCOM steps are 3 hours apart
192
+ with occasional gaps of up to 51 hours, which this bridges with a straight line; a store does
193
+ not yet record the longest gap it filled (:doc:`hycom`).
194
+ - **Float32 fields, full-precision coordinates.** Data variables are cast to Float32 for the
195
+ model; ``lat``, ``lon``, ``z`` and ``z_face`` keep full precision, since Float32 longitudes near
196
+ -74 resolve only about 8e-6 degrees.
197
+ - **Fill values.** Missing data is written as ``-9999`` (integers) or ``-9999.0`` (floats) in the
198
+ Zarr encoding, and as NaN in memory.
199
+ - **Time in seconds.** ``z-v3`` stores encode time as seconds since their first record, which
200
+ the model's clock uses directly.