tracmass.seagrid#
Retrieve and store daily ocean reanalysis data from Mercator Ocean.
- tracmass.seagrid.glorys.mask_fill(da)[source]#
Replace the fill values (land) in a GLORYS variable (lazy).
Masked points hold the fill value: no flow through land (velocities
uvel/vvel/wvel→ 0); tracers have no land value (→ NaN).- Parameters:
da (
xr.DataArray) – A variable fromopen_dataset(), named by its key ("uvel","temp", …).- Returns:
xr.DataArray– Same shape and Dask chunks.
- tracmass.seagrid.glorys.datadir(dtm='2020-01-01')[source]#
Return the local data directory for a given date, creating it if needed.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object.- Returns:
pathlib.Path– Path to the year-specific data directory.
- tracmass.seagrid.glorys.filename(dtm='2020-01-01', data_var='uvel')[source]#
Build the Zarr filename for a given dat and variable.
- tracmass.seagrid.glorys.retrieve(dtm='2020-01-01', data_var='uvel', force=False)[source]#
Download a single daily field from the Mercator THREDDS server and save it as Zarr.
Opens the remote dataset via OPeNDAP, selects the time step closest to
dtm, and writes the result to a local Zarr store.
- tracmass.seagrid.glorys.landmask(k=1)[source]#
GLORYS12 land mask on the T-cells of
grid_definition().- Parameters:
k (
int, optional) – 1-based model level. Default1(surface): land iskmt == 0. Deeper, the sea floor counts as land too (kmt < k).- Returns:
xr.DataArray– bool(y, x),Trueon land, withlon/latcoordinates. Seetracmass.seagrid.coast.landmask().- Return type:
- tracmass.seagrid.glorys.distance_to_land(k=1)[source]#
Distance (km) from each GLORYS12 T-cell centre to the nearest land cell.
- Parameters:
k (
int, optional) – 1-based model level whose land mask is used (seelandmask()). Default1(surface).- Returns:
xr.DataArray– float32(y, x)great-circle distance in km, 0 on land, withlon/latcoordinates. Seetracmass.seagrid.coast.distance_to_land().- Return type:
- tracmass.seagrid.glorys.open_dataset(dtm='2020-01-01', data_var=None, force=False, dask=True, mask=True)[source]#
Open a mercator dataset, downloading it first if necessary.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object for the desired time step.data_var (
str) – Variable key (one of ‘uvel’, ‘vvel’, ‘wvel’, ‘temp’, ‘salt’).force (
bool) – If True, re-download the file even if it already exists locally.mask (
bool, optional) – Replace fill values (land) with 0 for velocities and NaN for tracers. Default True.Falseleaves them in, for callers that first cut out a region and then mask just that withmask_fill()(masking a whole Zarr chunk to keep a small part of it is several times slower).
- Returns:
xarray.Dataset– Dataset containing the requested variable for the given date.
- tracmass.seagrid.glorys.rechunk_wvel(dtm1, dtm2=None, depth_chunk=10, path=None)[source]#
Rewrite cached
wvelZarr stores with depth_chunk-level chunks.wvelstores downloaded before 2026-10-08 hold each 1000 x 1000 tile as one 50-level chunk (the download chunkeddepthtbutwvelis ondepthw), so reading a few levels decompresses all 50 in one thread. The x/y chunks are kept. Each store is written next to the original, checked to hold identical values, and only then swapped in; stores that already have depth_chunk levels per chunk are skipped.Do not run it on days a tracking run is reading at the same time. A run opens each day’s store (and its chunk layout) a window before it reads the data; if the store is swapped in between, the read fails with
cannot reshape array of size 10000000 into shape (50,1000,1000). A run is usually faster than the rechunk, so a run that starts behind it catches up. Rechunk first, or rechunk days the run has already passed.- Parameters:
dtm1 (
strordatetime-like) – First day.dtm2 (
strordatetime-likeorNone, optional) – Last day (inclusive). Default: only dtm1.depth_chunk (
int, optional) – Levels per chunk. Default 10, asuvel/vvel.path (
strorpathlib.PathorNone, optional) – Rechunk this one store instead of the cachedwvelof dtm1 .. dtm2 (for testing on a copy).
- Returns:
listofpathlib.Path– The stores that were rewritten.- Raises:
RuntimeError – If a rewritten store does not match its original; the original is then left untouched.
- Return type:
Examples
>>> rechunk_wvel("2010-06-01", "2011-06-01")
- tracmass.seagrid.glorys.open_dataarray(dtm='2020-01-01', data_var='uvel', force=False, mask=True)[source]#
Open a mercator dataarray, downloading it first if necessary.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object for the desired time step.data_var (
str) – Variable key (one of ‘uvel’, ‘vvel’, ‘wvel’, ‘temp’, ‘salt’).force (
bool) – If True, re-download the file even if it already exists locally.mask (
bool, optional) – Mask fill values, seeopen_dataset(). Default True.
- Returns:
xarray.Dataset– Dataset containing the requested variable for the given date.
Retrieve and store daily ECCO2 cube92 ocean state estimate data.
Unlike the GLORYS12/Mercator THREDDS archive (one file per day, per
variable, discovered through a rolling filename), the APDRC GDS server
exposes each ECCO2 cube92 variable as a single OPeNDAP dataset spanning
the full 1992-01-04 – 2025-12-31 daily record. A requested date is
selected from that record by nearest-neighbour lookup on the remote
time coordinate and cached locally as a single-day Zarr store so
repeated access does not re-hit the network.
ECCO2 cube92 is also a plain regular lat/lon grid (0.25 deg, global),
not a curvilinear NEMO grid, so there are no separate mesh_hgr/mesh_zgr
files to derive geometry from. grid_definition() instead computes
cell areas analytically from the lat/lon spacing and derives the bottom
level index kmt from the land/below-seafloor pattern of a reference
uvel snapshot (see calc_kmt_dzt()).
The server’s native lon runs 0.125..359.875 (Prime Meridian at the
array seam); _center_on_prime_meridian() rolls every cached field to
-179.875..179.875 so 0 deg sits at the array centre, matching the
convention used elsewhere in the codebase.
- tracmass.seagrid.ecco2.datadir(dtm='2020-01-01')[source]#
Return the local data directory for a given date, creating it if needed.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object.- Returns:
pathlib.Path– Path to the year-specific data directory.
- tracmass.seagrid.ecco2.filename(dtm='2020-01-01', data_var='uvel')[source]#
Build the Zarr filename for a given date and variable.
- tracmass.seagrid.ecco2.retrieve(dtm='2020-01-01', data_var='uvel', force=False)[source]#
Download a single daily field from the APDRC GDS server and save it as Zarr.
Opens the remote ECCO2 cube92 dataset via OPeNDAP, selects the time step closest to
dtm, and writes the result to a local Zarr store.
- tracmass.seagrid.ecco2.calc_grid_spacing(lat, lon)[source]#
Compute T-cell face widths on a regular lat/lon grid.
- Parameters:
lat (
np.ndarray) – 1-D array of cell-centre latitudes in degrees, shape(jmt,).lon (
np.ndarray) – 1-D array of cell-centre longitudes in degrees, shape(imt,).
- Returns:
dxv (
np.ndarray) – Zonal cell width in meters (face crossed by meridional flux), shape(jmt, imt).dyu (
np.ndarray) – Meridional cell width in meters (face crossed by zonal flux), shape(jmt, imt).
- tracmass.seagrid.ecco2.calc_kmt_dzt(uvel0, lev)[source]#
Derive bottom-level index and layer thickness from a reference snapshot.
ECCO2 cube92 has no separate bathymetry file; land and below-seafloor cells carry an exact-zero velocity (see Notes), so the ocean depth at each column is recovered by counting non-zero levels.
- Parameters:
uvel0 (
np.ndarray) – Zonal velocity at a single reference time, shape(km, jmt, imt).lev (
np.ndarray) – 1-D array of depth-level centres in meters, shape(km,).
- Returns:
kmt (
np.ndarray) – 1-based bottom level index per column, shape(jmt, imt).dzt (
np.ndarray) – Layer thickness, zeroed below the seafloor, shape(km, jmt, imt).
Notes
The APDRC GDS gateway declares
missing_value/_FillValueas-1e23but actually serves exact0.0for land and below-seafloor cells (verified against known land and shallow-shelf columns), so the mask is built from exact equality rather than NaN/CF decoding.
- tracmass.seagrid.ecco2.grid_definition(dtm='2020-01-01', dask=True, force=False)[source]#
Build (and cache) the ECCO2 cube92 grid geometry.
- Parameters:
dtm (
strordatetime-like, optional) – Reference date used to derivekmtfrom the land/underwater NaN pattern of a singleuvelsnapshot. Default"2020-01-01".dask (
bool, optional) – If True (default), open the cached grid file with Dask chunking.force (
bool, optional) – If True, rebuild the grid file even if it already exists.
- Returns:
xarray.Dataset– Dataset withdxdy,dxv,dyu,dzt,kmt,lon,lat.
- tracmass.seagrid.ecco2.landmask(k=1)[source]#
ECCO2 land mask on the T-cells of
grid_definition().- Parameters:
k (
int, optional) – 1-based model level. Default1(surface): land iskmt == 0. Deeper, the sea floor counts as land too (kmt < k).- Returns:
xr.DataArray– bool(y, x),Trueon land, withlon/latcoordinates. Seetracmass.seagrid.coast.landmask().- Return type:
- tracmass.seagrid.ecco2.distance_to_land(k=1)[source]#
Distance (km) from each ECCO2 T-cell centre to the nearest land cell.
- Parameters:
k (
int, optional) – 1-based model level whose land mask is used (seelandmask()). Default1(surface).- Returns:
xr.DataArray– float32(y, x)great-circle distance in km, 0 on land, withlon/latcoordinates. Seetracmass.seagrid.coast.distance_to_land().- Return type:
- tracmass.seagrid.ecco2.open_dataset(dtm='2020-01-01', data_var=None, force=False, dask=True)[source]#
Open an ECCO2 cube92 dataset, downloading it first if necessary.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object for the desired time step.data_var (
str) – Variable key (one of ‘uvel’, ‘vvel’, ‘wvel’, ‘temp’, ‘salt’). IfNone, both velocity components are fetched and merged.force (
bool) – If True, re-download the file even if it already exists locally.dask (
bool) – If True (default), open the cached Zarr with Dask chunking.
- Returns:
xarray.Dataset– Dataset containing the requested variable(s) for the given date, with dims renamed to(z, y, x).
- tracmass.seagrid.ecco2.open_dataarray(dtm='2020-01-01', data_var='uvel', force=False, dask=True)[source]#
Open an ECCO2 cube92 dataarray, downloading it first if necessary.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object for the desired time step.data_var (
str) – Variable key (one of ‘uvel’, ‘vvel’, ‘wvel’, ‘temp’, ‘salt’).force (
bool) – If True, re-download the file even if it already exists locally.dask (
bool) – If True (default), open the cached Zarr with Dask chunking.
- Returns:
xarray.DataArray– Data array for the requested variable and date.
Retrieve and store daily Scripps Gulf of Guinea (GoG) MITgcm output.
The Scripps GoG regional MITgcm configuration (GG_i001) is served as
plain NetCDF files over HTTPS from https://sose.ucsd.edu/GoG/DATA/, one
file per day and variable group, e.g.
daily/GG_i001_2024-01-02_1day_UVEL_VVEL_top200m.nc. Unlike ECCO2
there is no OPeNDAP server, so retrieve() downloads whole files and
caches them unchanged under datadir(); open_dataset() opens
the cached copy.
The model uses an MITgcm Arakawa C-grid on a regular 1/64 deg lat/lon
mesh (1376 x 385 T-cells, 11W–10.5E, 1–7N). The velocity files cover
only the 320 T-cell rows 2–7N, keep MITgcm’s staggered dimensions
(UVEL on (Z, YC, XG): the west face of each T-cell; VVEL
on (Z, YG, XC): the south face, plus one extra row for the
northernmost north face), and carry their own face metrics (dyG,
dxG) and open fractions (hFacW, hFacS). Moving those faces
onto TRACMASS’s east/north convention is done in
tracmass.gcm.scrippsgog.
There is no hFacC in the velocity files. grid_definition()
rebuilds it from the binary Depth and delR grid files with
MITgcm’s partial-cell rule (hFacMin, see calc_hfac()) and
checks the result against the files’ hFacW/hFacS.
- tracmass.seagrid.scrippsgog.basedir()[source]#
Return the local root directory for the configured product.
- Returns:
pathlib.Path–/data/<disk>/scrippsgog/<product>, created if needed.
- tracmass.seagrid.scrippsgog.datadir(dtm='2024-01-02')[source]#
Return the local data directory for a given date.
- Parameters:
dtm (
strordatetime-like) – Date string or datetime-like object.- Returns:
pathlib.Path– Path to the year-specific daily data directory.
- tracmass.seagrid.scrippsgog.griddir()[source]#
Return the local directory holding the binary grid files.
- tracmass.seagrid.scrippsgog.filename(dtm='2024-01-02', data_var='uvel')[source]#
Build the remote (and cached) filename for a given date and variable.
- tracmass.seagrid.scrippsgog.url(dtm='2024-01-02', data_var='uvel')[source]#
Return the download URL of a daily file.
- tracmass.seagrid.scrippsgog.available_dates(data_var='uvel')[source]#
List the dates the server has files for.
- Parameters:
data_var (
str) – Variable key (one of ‘uvel’, ‘vvel’, ‘temp’, ‘salt’).- Returns:
pandas.DatetimeIndex– Sorted dates parsed from the server’s directory listing.
- tracmass.seagrid.scrippsgog.retrieve(dtm='2024-01-02', data_var='uvel', force=False)[source]#
Download a single daily file and cache it locally.
- Parameters:
- Returns:
pathlib.Path– Path to the cached file.- Raises:
FileNotFoundError – If the server has no file for dtm (see
available_dates()).
Examples
>>> from tracmass.seagrid import scrippsgog >>> for dtm in pd.date_range("2024-01-02", "2024-01-31"): ... scrippsgog.retrieve(dtm)
- tracmass.seagrid.scrippsgog.retrieve_grid(force=False)[source]#
Download the binary MITgcm grid files (
XC,YC,Depth, …).- Parameters:
force (
bool) – If True, re-download even if the files are already cached.- Returns:
pathlib.Path– The local grid directory (griddir()).
- tracmass.seagrid.scrippsgog.read_grid_field(name)[source]#
Read one binary MITgcm grid field (
XC,YC,Depth,RC).- Parameters:
name (
str) – Field name;<name>.data/<name>.metamust be ingriddir()(seeretrieve_grid()).- Returns:
np.ndarray– float32 array, shape(385, 1376)for 2-D fields (y first).
- tracmass.seagrid.scrippsgog.calc_hfac(depth, drf, hfac_min=0.2, hfac_min_dr=0.0)[source]#
Rebuild MITgcm’s T-cell open fraction
hFacCfrom bathymetry.- Parameters:
- Returns:
np.ndarray–hFacC, shape(km, jmt, imt), in[0, 1].
Notes
Follows MITgcm
ini_masks_etc: the raw fraction of each layer above the sea floor is rounded to 0 below half the minimum size, and up to the minimum size below it.
- tracmass.seagrid.scrippsgog.calc_kmt_dzt(hfac, drf)[source]#
Derive bottom-level index and layer thickness from
hFacC.- Parameters:
hfac (
np.ndarray) – Open fraction, shape(km, jmt, imt).drf (
np.ndarray) – Layer thicknesses (m), shape(km,).
- Returns:
kmt (
np.ndarray) – Number of open layers per column, shape(jmt, imt), int32. Land is 0.dzt (
np.ndarray) –drf * hfac(partial bottom cells), shape(km, jmt, imt).
- tracmass.seagrid.scrippsgog.grid_definition(dtm=None, dask=True, force=False)[source]#
Build (and cache) the GoG grid geometry on the velocity files’ T-cells.
- Parameters:
dtm (
strordatetime-likeorNone, optional) – Date of the reference velocity file whose rows, layers and face metrics define the grid. Default: the first file on the server’s start date (2024-01-02).dask (
bool, optional) – If True (default), open the cached grid file with Dask chunking.force (
bool, optional) – If True, rebuild the grid file even if it already exists.
- Returns:
xarray.Dataset– Dataset on(z, y, x)T-cells withkmt,dzt,hfac,dxdy,dxv,dyu, the 2-Dlons/latsand 1-Dlon/lat/zcoordinates.- Raises:
ValueError – If the rebuilt
hFacCdoes not reproduce the velocity file’shFacW/hFacS(wrongsettings["hfac_min"]or misaligned rows).
- tracmass.seagrid.scrippsgog.landmask(k=1)[source]#
GoG land mask on the T-cells of
grid_definition().- Parameters:
k (
int, optional) – 1-based model level. Default1(surface): land iskmt == 0. Deeper, the sea floor counts as land too (kmt < k).- Returns:
xr.DataArray– bool(y, x),Trueon land, withlon/latcoordinates. Seetracmass.seagrid.coast.landmask().- Return type:
- tracmass.seagrid.scrippsgog.distance_to_land(k=1)[source]#
Distance (km) from each GoG T-cell centre to the nearest land cell.
- Parameters:
k (
int, optional) – 1-based model level whose land mask is used (seelandmask()). Default1(surface).- Returns:
xr.DataArray– float32(y, x)great-circle distance in km, 0 on land, withlon/latcoordinates. Seetracmass.seagrid.coast.distance_to_land().- Return type:
Notes
The GoG domain is regional: land outside it is unknown, so distances near the open boundaries can be too large.
- tracmass.seagrid.scrippsgog.open_dataset(dtm='2024-01-02', data_var=None, force=False, dask=True)[source]#
Open a cached daily GoG file, downloading it first if necessary.
- Parameters:
dtm (
strordatetime-like) – Date of the daily file.data_var (
strorNone) – Variable key (one of ‘uvel’, ‘vvel’, ‘temp’, ‘salt’).None(default) opens the velocity file with bothuvelandvvel.force (
bool) – If True, re-download the file even if it already exists locally.dask (
bool) – If True (default), open with Dask chunking (the file’s own chunks).
- Returns:
xarray.Dataset– The file’s single time step, with the data variable(s) renamed to their keys andZrenamed toz. MITgcm’s staggered horizontal dims (XC/XG,YC/YG) and face metrics are kept as is.
- tracmass.seagrid.scrippsgog.open_dataarray(dtm='2024-01-02', data_var='uvel', force=False, dask=True)[source]#
Open one variable of a daily GoG file, downloading it if necessary.
- Parameters:
- Returns:
xarray.DataArray– Data array for the requested variable and date.
Land mask and distance to land on a seagrid model’s T-cells.
Shared by the per-model landmask / distance_to_land functions in
tracmass.seagrid.glorys, tracmass.seagrid.ecco2 and
tracmass.seagrid.scrippsgog. Each model passes its
grid_definition() dataset; everything else is grid-independent.
- tracmass.seagrid.coast.landmask(grid, k=1)[source]#
Land mask of a
grid_definition()dataset.- Parameters:
grid (
xr.Dataset) – A seagridgrid_definition()withkmt(the number of ocean levels per column; 0 on land) andlon/latcoordinates.k (
int, optional) – 1-based model level. Default1(the surface): land iskmt == 0. At deeper levels the sea floor counts as land too:kmt < k.
- Returns:
xr.DataArray– bool,(y, x),Trueon land, with the grid’slon/latcoordinates. NumPy-backed.- Raises:
ValueError – If k is below 1.
- Return type:
- tracmass.seagrid.coast.distance_to_land(mask)[source]#
Great-circle distance from every cell centre to the nearest land cell.
- Parameters:
mask (
xr.DataArray) – A land mask fromlandmask()(bool,(y, x),Trueon land, withlon/latcoordinates in degrees).- Returns:
xr.DataArray– float32,(y, x), in km, with the mask’s coordinates. 0 on land; NaN everywhere when the grid has no land cell.- Return type:
Notes
Distances run between cell centres: an ocean cell next to the coast is about one cell width from land, not half. The search uses a KD-tree on unit-sphere coordinates, so it is exact on curvilinear grids and across the date line. Only land cells with an ocean neighbour (8-neighbour) go into the tree: any other land cell is farther from the ocean. On a regional grid, land outside the domain is unknown, so distances near the open boundaries can be too large.
Debugging utilities for tracmass.seagrid.