1. Grids (hgrid · topo · vgrid)

Contents

1. Grids (hgrid · topo · vgrid)#

The first step of any CrocoDash workflow is defining the spatial domain: a horizontal grid (Grid), a bathymetry (Topo), and a vertical grid (VGrid).

        flowchart LR
    HG["hgrid<br/>(Grid)"] --> C["Case(...)"]
    TP["topo<br/>(Topo)"] --> C
    VG["vgrid<br/>(VGrid)"] --> C
    

CrocoDash re-exports these objects from mom6_forge with no modifications, so all the details — class methods, creation patterns, file formats — live in the mom6_forge documentation. This page is a short on-ramp that points you there.

What mom6_forge gives you#

For each of the three grid objects, mom6_forge provides both programmatic and interactive construction:

Object

Programmatic API

Interactive widget

Horizontal grid (Grid)

Grid(...), Grid.from_supergrid(...), Grid.subgrid_from_supergrid(...), Grid.from_projection(...)

GridCreator

Bathymetry (Topo)

Topo(...), Topo.from_topo_file(...), Topo.set_from_dataset(...), Topo.set_flat(...)

TopoEditor

Vertical grid (VGrid)

VGrid.uniform(...), VGrid.hyperbolic(...), VGrid.from_file(...)

VGridCreator

Notable features worth knowing about:

  • TopoEditor — ipywidgets-based bathymetry editor with undo/redo, version-controlled edits, and live plotting. Great for fixing isolated basins, carving channels, or smoothing coastlines before case creation.

  • Version-controlled bathymetry — Topo uses a per-domain TopoLibrary/ directory under the hood. Every edit is committed as a git-style operation, so you can replay, share, or undo bathymetry changes reproducibly.

  • Curvilinear grids — Grid.from_supergrid(...) works for both rectilinear (lon/lat) and curvilinear grids.

  • Polar domains — Grid.from_projection(...) builds an Arctic or Antarctic grid on a polar stereographic projection.

  • ESMF mesh + SCRIP output — the Topo object writes CICE grids, SCRIP grids, and ESMF meshes directly, which is what CESM needs for coupling.

  • runoff mapping helpers — mom6_forge.mapping is used internally by CrocoDash.forcing.runoff, but is also available if you need it directly.

Importing#

The only difference from vanilla mom6_forge is the import path. Replace the mom6_forge namespace with CrocoDash:

Instead of…

Use…

import mom6_forge.grid

import CrocoDash.grid

import mom6_forge.topo

import CrocoDash.topo

import mom6_forge.vgrid

import CrocoDash.vgrid

Everything else — class names, method signatures, parameters — is identical.

API reference#

The three grid classes and their widgets, as CrocoDash re-exports them. These are mom6_forge’s classes unchanged — this section exists because Sphinx does not follow import * re-exports into the auto-generated API docs.

class CrocoDash.grid.Grid(lenx: float, leny: float, nx: int = None, ny: int = None, resolution: float | None = None, xstart: float = 0.0, ystart: float | None = None, cyclic_x: bool = False, name: str | None = None, type: str = 'uniform_spherical')#

Bases: object

Horizontal MOM6 grid. The first step of constructing a MOM6 grid within the CESM simpler models framework is to create a Grid instance.

tlon#

array of t-grid longitudes

Type:

xr.DataArray

tlat#

array of t-grid latitudes

Type:

xr.DataArray

ulon#

array of u-grid longitudes

Type:

xr.DataArray

ulat#

array of u-grid latitudes

Type:

xr.DataArray

vlon#

array of v-grid longitudes

Type:

xr.DataArray

vlat#

array of v-grid latitudes

Type:

xr.DataArray

qlon#

array of corner longitudes

Type:

xr.DataArray

qlat#

array of corner latitudes

Type:

xr.DataArray

dxt#

x-distance between U points, centered at t

Type:

xr.DataArray

dyt#

y-distance between V points, centered at t

Type:

xr.DataArray

dxCv#

x-distance between q points, centered at v

Type:

xr.DataArray

dyCu#

y-distance between q points, centered at u

Type:

xr.DataArray

dxCu#

x-distance between y points, centered at u

Type:

xr.DataArray

dyCv#

y-distance between t points, centered at v

Type:

xr.DataArray

angle#

angle grid makes with latitude line

Type:

xr.DataArray

angle_q#

angle q-grid makes with latitude line

Type:

xr.DataArray

tarea#

T-cell area

Type:

xr.DataArray

static check_supergrid(supergrid: Dataset) → None#

Check if a given supergrid contains the necessary attributes and has consistent units.

Parameters:

supergrid (xarray.Dataset) – MOM6 Supergrid dataset

classmethod from_center(center_lat: float, center_lon: float, width_m: float, height_m: float, resolution_m: float, angle_deg: float = 0.0, name: str | None = None) → Grid#

Create a rotated rectangular grid centred at a geographic point.

Uses an azimuthal equidistant projection centred at (center_lat, center_lon) and rotates the domain by angle_deg clockwise from north. Useful for aligning a regional domain with a coastline feature — for example, placing one grid boundary perpendicular to an estuary mouth.

Parameters:
  • center_lat (float) – Geographic centre of the domain in degrees.

  • center_lon (float) – Geographic centre of the domain in degrees.

  • width_m (float) – Domain width (x) and height (y) in metres.

  • height_m (float) – Domain width (x) and height (y) in metres.

  • resolution_m (float) – Grid resolution in metres.

  • angle_deg (float, optional) – Clockwise rotation from north in degrees. Default 0 (north-up). Example: angle_deg=45 places the x-axis along a NE–SW estuary mouth.

  • name (str, optional) – Name of the grid.

Return type:

Grid

classmethod from_esmf_mesh(path: str, name: str | None = None) → Grid#

Create a Grid instance from a supergrid file.

Parameters:
  • path (str) – Path to the supergrid file to be written

  • name (str, optional) – Name of the new grid. If provided, it will be used as the name of the grid. If not provided, the name will be derived from the file name.

Returns:

The Grid instance created from the supergrid file.

Return type:

Grid

classmethod from_projection(crs, x_min: float, x_max: float, y_min: float, y_max: float, resolution_m: float, name: str | None = None) → Grid#

Create a Grid from projected coordinate extents.

Builds a uniform grid in the given pyproj CRS (e.g., polar stereographic, Lambert conformal) and reprojects to geographic coordinates. Grid metrics are computed using exact great-circle geometry, making this accurate at high latitudes where RectilinearCartesianSupergrid degrades.

Parameters:
  • crs (pyproj.CRS, int, or str) –

    Map projection. Examples:

    ”EPSG:3995” — Arctic Polar Stereographic “EPSG:3031” — Antarctic Polar Stereographic

  • x_min (float) – Projected x extent in metres.

  • x_max (float) – Projected x extent in metres.

  • y_min (float) – Projected y extent in metres.

  • y_max (float) – Projected y extent in metres.

  • resolution_m (float) – Grid resolution in metres.

  • name (str, optional) – Name of the grid.

Return type:

Grid

classmethod from_supergrid(path: str, name: str | None = None) → Grid#

Create a Grid instance from a supergrid file.

Parameters:
  • path (str) – Path to the supergrid file to be written

  • name (str, optional) – Name of the new grid. If provided, it will be used as the name of the grid. If not provided, the name will be derived from the file name.

Returns:

The Grid instance created from the supergrid file.

Return type:

Grid

classmethod from_supergrid_ds(ds: Dataset, name: str | None = None) → Grid#

Create a Grid instance from a supergrid file.

Parameters:
  • ds (xr.Dataset) – xarray Dataset of the supergrid file to be written

  • name (str, optional) – Name of the new grid. If provided, it will be used as the name of the grid.

Returns:

The Grid instance created from the supergrid file.

Return type:

Grid

classmethod get_bounding_boxes(hgrid)#

Extract lat/lon bounding boxes for each edge of a regional MOM6 grid. This function is used when subsetting global datasets (e.g. GLORYS) down to the lat/lon ranges required for efficient regridding:

  • north, south, east, west boundaries

  • Entire domain initial condition files

Parameters:

hgrid (Grid or xarray.Dataset in the supergrid format)

Returns:

A dictionary containing bounding boxes for:
  • ”east”

  • ”west”

  • ”north”

  • ”south”

  • ”ic” (full domain for initial conditions)

Each box is {"lon_min", "lon_max", "lat_min", "lat_max", "crosses_antimeridian"}. lon_min is always a longitude in [-180, 180) and lon_max is lon_min plus the width of the box, so the pair always names a contiguous eastward arc and lon_max - lon_min is its width.

A box straddling the antimeridian therefore carries lon_max > 180 – 170 to 190, say – and sets crosses_antimeridian. A caller selecting with lon_min <= lon <= lon_max from a source on [-180, 180] has to branch on that flag and take the two pieces separately. Wrapping lon_max down to -170 first and comparing would select nothing.

Return type:

dict

get_esmf_ready_tracer_ds()#

This is to generate a ds that esmf/xesmf can use for regridding. It contains the tlat and tlon coordinates and the area variable (tarea) that can be used as weights for conservative regridding.

get_indices(tlat: float, tlon: float) → tuple[int, int]#

Get the i, j indices of a given tlat and tlon pair.

Parameters:
  • tlat (float) – The latitude value.

  • tlon (float) – The longitude value.

Returns:

The j, i indices of the given tlat and tlon pair.

Return type:

Tuple[int, int]

static is_cyclic_x(supergrid) → bool#

Check if a given supergrid x coordinate array is cyclic along the x-axis.

Parameters:

supergrid (xr.DataArray or np.array or SupergridBase) – Supergrid to check for cyclic x.

is_rectangular(atol=0.001) → bool#

Check if the grid is a rectangular lat-lon grid by comparing the first and last rows and columns of the tlon and tlat arrays.

Parameters:

atol (float, optional) – Absolute tolerance in degrees for the lat/lon comparisons. An absolute (rather than relative) tolerance is used because the coordinates are angles: the acceptable deviation must not scale with longitude/latitude magnitude.

static is_tripolar(supergrid) → bool#

Check if the given supergrid x coordinates form a tripolar grid.

Parameters:

supergrid (xr.Dataset or xr.DataArray or np.array or SupergridBase) – Supergrid to check if tripolar. Anything carrying a 2D x coordinate array will do, matching is_cyclic_x above.

property kdtree: cKDTree#

KDTree for fast nearest neighbor search.

property lenx: float#

Length of the grid in the x-direction.

property leny: float#

Length of the grid in the y-direction.

property name: str#

Name of the grid.

property nx#

Number of cells in x-direction.

property ny#

Number of cells in y-direction.

plot(property_name)#

Plot a given grid property using cartopy. Warning: cartopy module must be installed seperately

Parameters:

property_name (str) – The name of the grid property to plot, e.g., ‘tlat’.

plot_cross_section(property_name, iy=None, ix=None)#

Plot the cross-section of a given grid metric.

Parameters:
  • property_name (str) – The name of the grid property to plot, e.g., ‘tlat’.

  • iy (int) – y-index of the cross section

  • ix (int) – x-inted of the cross section

classmethod subgrid_from_supergrid(path: str, llc: tuple[float, float], urc: tuple[float, float], name: str) → Grid#

Create a Grid instance from a subset of a supergrid file.

Parameters:
  • path (str) – Path to the full supergrid file to be carved out.

  • llc (tuple[float, float]) – Lower left corner coordinates (lat, lon) of the subdomain to extract

  • urc (tuple[float, float]) – Upper right corner coordinates (lat, lon) of the subset to extract

  • name (str) – Name of the subgrid

Returns:

The Grid instance created from the supergrid file.

Return type:

Grid

property supergrid: SupergridBase#

MOM6 supergrid contains the grid metrics and the areas at twice the nominal resolution (by default) of the actual computational grid.

update_supergrid(xdat: array, ydat: array, grid_type=None) → None#

Update the supergrid x and y coordinates. Running this method also updates the nominal grid coordinates and metrics.

Parameters:
  • xdat (np.array) – 2-dimensional array of the new x coordinates.

  • ydat (np.array) – 2-dimensional array of the new y coordinates.

  • grid_type (str) – The grid type of the passed in x and y arrays

write_supergrid(path: str | None = None, author: str | None = None) → None#

Write supergrid to a netcdf file. The supergrid file is to be read in by MOM6 during runtime.

Parameters:
  • path (str, optional) – Path to the supergrid file to be written.

  • author (str, optional) – Name of the author. If provided, the name will appear in files as metadata.

class CrocoDash.topo.Topo(grid, min_depth, channel_widths=None, version_control_dir='TopoLibrary', git=False)#

Bases: object

Bathymetry Generator for MOM6 grids (mom6_forge.grid.Grid).

apply_edit(cmd, skip_version_control=False, cmd_type=CommandType.COMMAND)#

Apply an edit command aware of version control. If version control is enabled, the command is executed through the TopoCommandManager (TCM) to ensure it is recorded in the version history and can be undone/redone. If version control is disabled, the command is executed directly without recording.

Parameters:
  • cmd (Command) – The command to be applied.

  • skip_version_control (bool) – If True, the command will be executed without recording in version control even if version control is enabled. This can be useful for programmatic changes that should not be part of the user-facing version history.

  • cmd_type (CommandType) – The type of the command, used for version control categorization. Ignored if skip_version_control is True or if version control is disabled.

apply_ridge(height, width, lon, ilat)#

Apply a ridge to the bathymetry.

Parameters:
  • height (float) – Height of the ridge to be added.

  • width (float) – Width of the ridge to be added.

  • lon (float) – Longitude where the ridge is to be centered.

  • ilat (pair of integers) – Initial and final latitude indices for the ridge.

property basintmask#

Ocean domain mask at T grid. Seperate number for each connected water cell, 0 if land.

Labels are contiguous, starting at 1, and the basin of greatest total area carries the highest label. The remaining labels are in no particular order.

On a zonally periodic grid (cyclic_x), the components touching the i=0 and i=nx-1 columns of a common row are merged, so a basin straddling the seam is labeled once rather than twice.

clear_user_mask()#
compute_stats(nx_sub, ny_sub, mask_hmin)#

Compute per-cell depth statistics by uniform sub-sampling.

Results are stored on stats so a second call with the same source file returns immediately without recomputation. (Originally created by Frank Bryan in Fortran for NCAR/tx2_3, reimplemented in Python)

Parameters:
  • src (SourceBathy (part of class))

  • nx_sub (int)

  • ny_sub (int)

  • mask_hmin (float)

Return type:

xr.Dataset — OCN_FRAC, D_mean, D_min, D_max, D2_mean.

property depth#
diagnose_resolution(radius=6371000.0)#

Print resolution diagnostics comparing the model grid to a source bathymetry dataset, and recommend whether Cressman interpolation / stats-based masking is worthwhile.

The recommendation threshold is a resolution ratio of 12x (model dx / dataset dx), equivalent to ~0.05° (~5 km) for GEBCO 15-arcsecond source data. This matches the criterion used by the tx2_3 global workflow (interp_smooth.f90) and might be the scale at which ocean-aware Cressman interpolation meaningfully improves coastal depth estimates over standard xesmf conservative regridding.

Parameters:
  • src (SourceBathy (provided internally by the class)) – Source bathymetry object.

  • radius (float, optional) – Radius of the Earth in meters, used to convert source dataset lat/lon spacing to approximate physical spacing in meters at the domain’s mid-latitude. Default is 6.371e6 m.

Returns:

True if Cressman / stats-based masking is recommended (ratio >= 12x and the clipped source dataset has at most 1e6 points), False otherwise.

Return type:

bool

direct_cressman_interp(smooth_scl=2.0, cressman_exp=2.0, weights_path=None)#

Assign ocean depths using Cressman distance-weighted interpolation. Mirrors interp_smooth.f90 from the tx2_3 topography workflow.

For each ocean T-cell a smoothing radius L = smooth_scl * sqrt(cell_area) is computed. Source ocean points within L are averaged with weights

\[w = \left(\frac{L^2 - r^2}{L^2 + r^2}\right)^{c}\]

where r is the great-circle arc distance and c = cressman_exp. Only source points with positive depth (ocean) contribute, so depth estimates are never contaminated by land elevations.

Weights are computed by compute_cressman_weights(), optionally saved to an ESMF-compatible netCDF, and applied through xe.Regridder — all orchestrated by regrid_dataset_via_cressman(). Cells that receive no source coverage are filled by iterative neighbour averaging (up to 100 passes).

Parameters:
  • smooth_scl (float) – Smoothing scale multiplier for the Cressman radius. Default 2.0.

  • cressman_exp (float) – Exponent for the Cressman weight function. Default 2.0.

  • weights_path (str or Path or None) – Where to save the ESMF weights netCDF. If None (default), the weights are kept in memory and nothing is written.

edit_depth(indices, values)#

Edit depth at specific indices with version control.

Parameters:
  • indices (list of tuples) – List of (j, i) indices to modify.

  • values (list or array-like) – New depth values for each index.

erase_disconnected_basin(i, j)#

Erase every basin but the one containing cell (i, j). A no-op if that cell is land.

erase_selected_basin(i, j)#

Erase the basin containing cell (i, j). A no-op if that cell is land.

fill_inland_lakes_and_channels()#

Fill in one-cell-wide channels and inland lakes. This removes more narrow inlets, but can also connect extra islands to land.

classmethod from_esmf_mesh(mesh_path, radius=6371000.0, min_depth=0.0, version_control_dir='TopoLibrary', git=False)#

Construct a topo object from the ESMF mesh + Mask, there is no depth associated with this

Parameters:
  • mesh_path (str or xr.Dataset) – Path to ESMF mesh file to read, or an already-opened Dataset.

  • radius (float, optional) – Radius of the Earth (m). Default is _DEFAULT_RADIUS.

  • min_depth (float, optional) – Minimum water column depth (m). Columns with shallower depths are to be masked out. Default is 0.0.

  • git (bool, optional) – Passed through to Topo.__init__. See Topo docstring for details. Default is False.

classmethod from_topo_file(grid, topo_file_path, min_depth=0.0, varname='depth', version_control_dir='TopoLibrary', git=False, channel_widths=None)#

Create a bathymetry object from an existing topog file.

Parameters:
  • grid (mom6_forge.grid.Grid) – horizontal grid instance for which the bathymetry is to be created.

  • topo_file_path (str) – Path to an existing MOM6 topog file.

  • min_depth (float, optional) – Minimum water column depth (m). Columns with shallower depths are to be masked out.

  • varname (str, optional) – Name of the variable representing ocean depth in the dataset. Default is “depth”.

  • git (bool, optional) – Passed through to Topo.__init__. See Topo docstring for details.

  • version_control_dir (str, optional) – Directory for version control. Default is “TopoLibrary”.

  • channel_widths (str | Path | ChannelWidthList, optional) – Channel width constraints. Can be a filepath to load from, a ChannelWidthList object, or None.

classmethod from_version_control(folder_path: str | Path, channel_widths=None)#

Create a bathymetry object from an existing version-controlled bathymetry folder.

Parameters:
  • folder_path (str | Path) – Path to an existing bathymetry folder created by mom6_forge with version control enabled.

  • channel_widths (str | Path | ChannelWidthList, optional) – Channel width constraints. Can be a filepath to load from, a ChannelWidthList object, or None.

gen_topo_ds(title=None)#

Write the TOPO_FILE (bathymetry file) in xarray Dataset.

Parameters:

title (str, optional) – File title.

generate_mask_from_landfrac_file(landfrac_filepath, landfrac_name, xcoord_name, ycoord_name, cutoff_frac=0.5, method='bilinear')#

Given a dataset containing land fraction, generate and apply ocean mask.

Parameters:
  • landfrac_filepath (str) – Path the netcdf file containing the land fraction field.

  • landfrac_name (str) – The field name corresponding to the land fraction (e.g., “landfrac”).

  • xcoord_name (str) – The name of the x coordinate of the landfrac dataset (e.g., “lon”).

  • ycoord_name (str) – The name of the y coordinate of the landfrac dataset (e.g., “lat”).

  • cutoff_frac (float) – Cells with landfrac > cutoff_frac are deemed land cells.

  • method (str) – Mapping method for determining the ocean mask (lnd -> ocn)

generate_mask_from_naturalearth(resolution='10', version='v5_1_2')#

Generate and apply a land mask using regionmask’s Natural Earth dataset. (Recommended by Fred Castruccio)

Parameters:
  • resolution (str) – Resolution of the Natural Earth land dataset. One of “10”, “50”, “110” (minutes).

  • version (str) – Version of the Natural Earth dataset in regionmask. e.g. “v5_1_2”.

generate_mask_from_stats_ocean_frac(mask_threshold=0.5)#

Generate an ocean mask by uniform sub-sampling of the source bathymetry.

Mirrors the algorithm in tx2_3’s create_model_topo.f90. For each T-cell, distributes nx_sub x ny_sub interior points via bilinear interpolation of the Q-point corners and snaps each to the nearest source pixel. A cell is ocean if its ocean sub-point fraction (OCN_FRAC) meets or exceeds mask_threshold.

Parameters:

mask_threshold (float, optional) – Minimum OCN_FRAC for a cell to be classified as ocean. Default 0.5.

Returns:

Binary ocean mask on the T-grid (1 = ocean, 0 = land), dims ["ny", "nx"].

Return type:

xr.DataArray

Notes

compute_stats must be called before this method. Per-cell depth statistics (D_mean, D_min, D_max, D2_mean) are stored on the source bathymetry object for use by this and other downstream methods.

property has_version_control#
keep_largest_basin()#

Remove every disconnected ocean basin except the largest one.

Basins are the connected components of the ocean mask (4-connectivity, and wrapping in x when the grid is cyclic). basintmask gives the basin of greatest total area the highest label, so that one is kept and every other basin is masked out as land. This is a no-op when the domain holds at most one basin.

property land_fillval#

Depth value assigned to land cells when mask is applied. Default is 0.0 (dry).

property masked_depth#

Computed depth array with masking applied (m). Positive below MSL.

This is a computed property that applies land/ocean masking on-the-fly. When a user mask is set, returns masked depth: ocean cells enforced to at least min_depth+0.1, land cells set to _land_fillval. When mask is None, derives mask from raw depth (cells > min_depth are ocean).

Note: Index-based assignment like topo.masked_depth[j, i] = value will not persist because this property is computed on-the-fly. To modify depth, use topo.depth = new_array or topo.edit_depth().

property max_depth#

Maximum water column depth.

property min_depth#

Minimum water column depth. Columns with shallow depths are to be masked out.

mpi_set_depth_from_xesmf(*, bathymetry_path, longitude_coordinate_name, latitude_coordinate_name, vertical_coordinate_name, is_input_positive_below_msl=False, output_dir=PosixPath('.'), verbose=True)#

Prepare input files for MPI-parallel bathymetry regridding with ESMF_Regrid.

Writes bathymetry_original.nc (source) and bathymetry_unfinished.nc (destination grid shell) to output_dir. The user then runs ESMF_Regrid externally with MPI, and finally calls fill_inland_lakes_and_channels() to complete post-processing. Use this instead of set_depth_from_xesmf when the domain is too large to regrid within a single Python process.

Parameters:
  • bathymetry_path (str) – Path to the netCDF file with the source bathymetry.

  • longitude_coordinate_name (str) – Name of the longitude coordinate in the source dataset (e.g. 'lon' for GEBCO).

  • latitude_coordinate_name (str) – Name of the latitude coordinate in the source dataset (e.g. 'lat' for GEBCO).

  • vertical_coordinate_name (str) – Name of the vertical/elevation coordinate in the source dataset (e.g. 'elevation' for GEBCO).

  • is_input_positive_below_msl (bool, optional) – Set True if the source vertical coordinate is positive downwards (depth convention). Default: False.

  • output_dir (str or Path, optional) – Directory where the two netCDF files are written. Default: current directory.

  • verbose (bool, optional) – Print step-by-step MPI regridding instructions. Default: True.

point_is_ocean(lons, lats)#

Given a list of coordinates, return a list of booleans indicating if the coordinates are in the ocean (True) or land (False)

property qmask#

Ocean domain mask on Q grid. 1 if ocean, 0 if land.

send_entire_depth_change_to_tcm(depth, skip_version_control=False)#

This function takes an entire depth change and adds it through the TopoCommandManager (TCM) or directly if skip_version_control is enabled. Modifies _depth, preserves mask.

set_bowl(max_depth, dedge, rad_earth=6378000.0, expdecay=400000.0)#

Create a bowl-shaped bathymetry. Same effect as setting the TOPO_CONFIG parameter to “bowl”.

Parameters:
  • max_depth (float) – Maximum depth of model in the units of D.

  • dedge (float) – The depth [Z ~> m], at the basin edge

  • rad_earth (float, optional) – Radius of earth

  • expdecay (float, optional) – A decay scale of associated with the sloping boundaries [m]

set_depth_from_stats(statistic)#

Set the topo depth to a statistic computed by compute_stats.

Parameters:

statistic (str) – Which depth statistic to use. Must be one of the “D_*” keys in self.src.stats (e.g. “mean”, “min”, “max”).

set_depth_from_xesmf(output_dir=PosixPath('.'), write_to_file=False, regridding_method='bilinear')#

Regrid the source bathymetry onto the model grid using xESMF.

This code was originally written by Ashley Barnes in regional_mom6 (COSIMA/regional-mom6) and adapted for this package.

Requires that set_src has been called first (or that the source dataset has been set via set_from_dataset).

Parameters:
  • output_dir (str or Path, optional) – Directory where intermediate files are written when write_to_file=True. Default: current directory.

  • write_to_file (Optional[bool]) – Whether to write the source and unfinished destination grids to netCDF before regridding. Default: False.

  • regridding_method (Optional[str]) – The xESMF regridding method to use. Default: 'bilinear'.

set_depth_via_topog_file(topog_file_path, varname='depth', skip_version_control=False)#

Apply a bathymetry read from an existing topog file

Parameters:
  • topog_file_path (str) – absolute path to an existing MOM6 topog file

  • varname (str) – Name of the variable representing ocean depth in the dataset.

set_flat(D)#

Create a flat bottom bathymetry with a given depth D.

Parameters:

D (float) – Bathymetric depth of the flat bottom to be generated.

set_from_dataset(bathymetry_path, longitude_coordinate_name, latitude_coordinate_name, vertical_coordinate_name, fill_channels=False, is_input_positive_below_msl=False, output_dir=PosixPath('.'), write_to_file=False, mask_method=None, depth_method=None, regridding_method='bilinear', **kwargs)#

This is a high-level workflow function that runs multiple steps in sequence to set the bathymetry from a source dataset, with optional masking and depth method choices. It is designed to be opinionated and make recommendations based on resolution diagnostics, but users can override the defaults by specifying mask_method and depth_method. The workflow is as follows: 1. Set the source dataset (this will not modify the depth or mask yet,

it just loads the dataset and prepares it for regridding)

  1. Diagnose whether to use stats-based masking and Cressman interpolation based on resolution comparison between the source dataset and the model grid

  2. Apply a mask based on the user’s choice or the resolution diagnostics recommendation (options are ‘naturalearth’, ‘ocean_frac’, ‘dataset’, ‘manual’, or None)

  3. Set the depth based on the user’s choice or the resolution diagnostics recommendation (options are ‘stats’, ‘xesmf’, or None)

  4. Call fill_inland_lakes_and_channels() to finish processing the bathymetry (fill channels, apply mask, etc.)

Parameters:
  • (str) (vertical_coordinate_name)

  • (str)

  • (str)

  • (str)

  • (bool (write_to_file)

  • optional) (The xESMF regridding method to use when depth_method is 'xesmf' (or when xesmf is chosen automatically). Default is 'bilinear'.)

  • (bool

  • optional)

  • Path (output_dir (str or)

  • optional)

  • (bool

  • optional)

  • None (depth_method (str or)

  • optional)

  • None

  • optional)

  • (str (regridding_method)

  • optional)

  • **kwargs (Additional keyword arguments needed for specific mask or depth methods. For example, if mask_method is 'ocean_frac', then kwargs should include 'nx_sub', 'ny_sub', and 'mask_hmin' for the sub-sampling stats calculation.)

set_spoon(max_depth, dedge, rad_earth=6378000.0, expdecay=400000.0)#

Create a spoon-shaped bathymetry. Same effect as setting the TOPO_CONFIG parameter to “spoon”.

Parameters:
  • max_depth (float) – Maximum depth of model in the units of D.

  • dedge (float) – The depth [Z ~> m], at the basin edge

  • rad_earth (float, optional) – Radius of earth

  • expdecay (float, optional) – A decay scale of associated with the sloping boundaries [m]

set_src(bathymetry_path, longitude_coordinate_name, latitude_coordinate_name, vertical_coordinate_name, is_input_positive_below_msl=False, buf=0.5)#

Set a SourceBathy into a class object called src

property src#

SourceBathy object representing the source bathymetry dataset sliced to the topo grid extent. This is set by set_src() when a new source bathymetry is specified, and can be accessed for any source dataset.

property stats#
property supergridmask#

Ocean domain mask on supergrid. 1 if ocean, 0 if land.

property tmask#

Ocean domain mask at T grid. 1 if ocean, 0 if land.

This is a derived mask computed from the depth property. The computation depends on whether a user mask has been set:

  • If _user_mask is None: Returns a mask derived from raw depth (_depth). Cells with depth > min_depth are marked as ocean (1), otherwise land (0).

  • If _user_mask is set: Returns a mask set by the user. The depth property will apply this mask to the raw depth, ensuring that ocean cells are at least min_depth+0.1 and land cells are set to 0.

This design means tmask is always consistent with the current depth state, whether driven by raw bathymetry or by a manually applied mask.

property umask#

Ocean domain mask on U grid. 1 if ocean, 0 if land.

property user_mask#

Optional binary ocean/land mask. 1 if ocean, 0 if land. When set, the depth property applies masking: ocean cells enforced greater than min_depth+0.1, land cells set to _land_fillval.

property vmask#

Ocean domain mask on V grid. 1 if ocean, 0 if land.

write_cice_grid(file_path)#

Write the CICE grid file in netcdf format. The written file is to be read in by CICE during runtime.

Parameters:

file_path (str) – Path to CICE grid file to be written.

write_esmf_mesh(file_path, title=None)#

Write the ESMF mesh file

Parameters:
  • file_path (str) – Path to ESMF mesh file to be written.

  • title (str, optional) – File title.

write_scrip_grid(file_path, title=None)#

Write the SCRIP grid file. In latest CESM versions, SCRIP grid files are no longer required and are replaced by ESMF mesh files. However, SCRIP files are still needed to generate custom ocean-runoff mapping files.

Parameters:
  • file_path (str) – Path to SCRIP file to be written.

  • title (str, optional) – File title.

write_topo(file_path, title=None)#

Write the TOPO_FILE (bathymetry file) in netcdf format. The written file is to be read in by MOM6 during runtime.

Parameters:
  • file_path (str) – Path to TOPO_FILE to be written.

  • title (str, optional) – File title.

Note

If channel_widths is not empty, remember to also write those constraints using channel_widths.write(channel_file_path).

write_ww3_input(file_dir, grid_alias, boundary_edges=None, open_boundary=None, cpl_dt=1800.0)#

Write the text-based WW3 input files ww3_grid.inp, [grid_alias]_x.inp, [grid_alias]_y.inp, [grid_alias]_mapsta.inp, [grid_alias]_bottom.inp, which are to be read by the WW3 mod_def creator before runtime to generate the WW3 grid files.

Parameters:
  • file_dir (str) – Directory to write the WW3 input files to.

  • grid_alias (str) – The alias for the grid, which will be used in the file names of the WW3 input files.

  • boundary_edges (None, str or iterable of str, optional) – Domain edges whose ocean cells become WW3 active boundary points (mapsta status 2): any of “south” (j=0), “north” (j=ny-1), “west” (i=0), “east” (i=nx-1). None (default) selects all four edges of a non-cyclic (regional) grid and no edge of a cyclic-x grid, so a global grid does not declare boundary points it has no data for; a zonally periodic band that is open to the south and north lists them explicitly. An empty list writes a plain land/sea mask; ww3_grid then excludes the perimeter sea cells. Spectral boundary data reach status-2 points via ww3_bounc / nest.ww3; without it they stay at zero energy, so whatever generates the spectra should list the edges it covers.

  • open_boundary (bool, optional) – Deprecated; use boundary_edges. True is the default edge set, False is no edges.

  • cpl_dt (float, optional) – Wave coupling interval in seconds (WAV_NCPL), which the time steps are derived from. Defaults to the CESM value of 1800 s.

Raises:

ValueError – If boundary_edges names an unknown edge, names the east or west edge on a grid that is reentrant in x, or the grid is tripolar (the closure written has no ‘TRPL’ case). Raised before anything is written.

ww3_min_grid_spacing()#

Smallest cell spacing on the grid, in meters.

ww3_timesteps(cpl_dt=1800.0)#

WW3 time steps for this grid.

See ww3_timesteps_from_spacing() for the CFL reasoning.

Parameters:

cpl_dt (float, optional) – Wave coupling interval in seconds (WAV_NCPL), 1800 s in CESM by default. dtmax is derived from it rather than taken as given.

class CrocoDash.vgrid.VGrid(dz: ndarray, name=None)#

Bases: object

Vertical grid class.

dz#

Array of vertical grid spacings

Type:

np.ndarray

nk#

Number of vertical levels

Type:

int

depth#

Total depth of the vertical grid

Type:

float

z#

Array of layer center depths

Type:

np.ndarray

property depth#

Total depth of the water column in meters.

classmethod from_file(filename: str, variable_name: str = 'dz', variable_type: Literal['layer_thickness', 'cell_center', 'cell_interface'] = 'layer_thickness', name: str = None)#

Create a vertical grid from an existing vertical grid file.

Parameters:
  • filename (str) – Name of the NetCDF file containing the vertical grid

  • coordinate_name (str, default: "dz") – Name of the variable to access within the given NetCDF file to get a vertical coordinate.

  • coordinate_type ({"layer_thickness", "cell_center", "cell_interface"}, default: "layer_thickness") –

    Type of vertical coordinate information given by the file and variable.

    • layer_thickness: specifies the thickness of each layer in the vertical grid. Size of n for n layers.

    • cell_center: gives the depth at the center of each vertical cell. Size of n for n layers.

    • cell_interface: gives the depth at the interface between each vertical cell. Size of n+1 for n layers.

classmethod hyperbolic(nk: int, depth: float, ratio: float, name: str = None)#

Create a hyperbolic vertical grid instance. (Adapted from regional-mom6)

Parameters:
  • nk (int) – Number of vertical levels

  • ratio (float) – Target ratio of top to bottom layer thicknesses

  • depth (float) – Total depth of the water column (meters)

  • name (str, optional) – Name of the vertical grid

property nk#

Number of vertical levels.

classmethod uniform(nk: int, depth: float, name: str = None)#

Create a uniform vertical grid instance.

Parameters:
  • nk (int) – Number of vertical levels

  • depth (float) – Total depth of the water column (meters)

  • name (str, optional) – Name of the vertical grid

write(filename: str, message: str = None, author: str = None)#

Write the vertical grid (in thickness) to a NetCDF file.

Parameters:

filename (str) – Name of the NetCDF file to write

write_z_file(filename: str)#

Write the vertical grid to a NetCDF file with interface and midpoints depths

Parameters:

filename (str) – Name of the NetCDF file to write

property zi#

Array of vertical grid cell interface depths (meters) - size nk+1. Assumes there is a surface interface at 0 meters.

property zl#

Array of vertical grid cell center depths (meters).

class CrocoDash.grid_creator.GridCreator(*args: t.Any, **kwargs: t.Any)#

Bases: HBox

Interactive Jupyter widget for creating and saving MOM6 horizontal grids.

The widget has two modes depending on how it is constructed:

Create Mode (GridCreator())#

Select a creation method, then press Select Region and interact with the map:

Lat/Lon Cornersdrag a rectangle on the PlateCarree map →

uniform-degree Grid via Grid(lenx, leny, ...)

From Centerset width/height/resolution/angle, click once to place the

domain centre → Grid.from_center(...)

From Projectionset a CRS + resolution, drag a rectangle on the native

projection map → Grid.from_projection(...)

Edit Mode (GridCreator(grid=some_latlon_grid))#

Accepts a lat/lon grid only — init args are backed out from the supergrid properties and exposed as live sliders. Passing a projected grid raises ValueError because the creation parameters are not stored in the supergrid file. Projected grids created within this session can be edited via their Recreate panel (the session holds the init args in memory).

Library#

Grids are saved as NetCDF supergrids under <working_dir>/GridLibrary/. The dropdown lists all grid_*.nc files there. Loading a projected grid from the library is not supported (parameters cannot be recovered from the file).

Map projection#

Entering “From Projection” mode switches the cartopy axes to the native projection for the selected CRS (preset EPSG codes only; unknown codes fall back to PlateCarree). All other modes use PlateCarree.

class CrocoDash.topo_editor.TopoEditor(*args: t.Any, **kwargs: t.Any)#

Bases: HBox

apply_edit(cmd)#

Apply an edit command, update the UI, and autosave the working state.

clear_user_mask(b)#

Clear the manual mask if it exists.

construct_control_panel()#

Construct the control panel widgets for the topography editor.

This includes controls for display mode, cell editing, undo/redo, snapshots, and git/domain management. The controls are grouped into logical sections for clarity.

construct_interactive_plot()#

Construct the interactive matplotlib plot for the topography editor.

This sets up the main map display, colorbar, and coordinate formatting. The plot is embedded in a widget for use in the Jupyter interface.

construct_observances()#

Attach event observers and callbacks to all interactive widgets and plot elements.

erase_disconnected_basin(b)#

Erase all disconnected basins in the topography.

erase_selected_basin(b)#

Erase the basin associated with the currently selected cell.

property has_version_control#

Check if the topo’s has version control.

on_depth_change(change)#

Handle changes to the depth specifier for the selected cell.

on_double_click(event)#

Handle double-click events on the plot to select a cell.

on_git_checkout(b)#

Checkout the specified git branch.

on_git_create_branch(b)#

Create a new git branch

on_min_depth_change(change)#

Handle changes to the minimum depth specifier.

on_tag(_btn=None)#

Save the current state as a snapshot and commit it to the repository.

redo_last_edit(b=None)#

Redo the last undone edit command and update the UI.

refresh_display_mode(change)#

Refresh the display mode of the topography plot based on the selected mode.

reset(change)#

Reset the topo to its original state and update the UI.

trigger_refresh()#

Trigger a refresh of the interactive plot and min depth specifier.

undo_last_edit(b=None)#

Undo the last edit command and update the UI.

update_undo_redo_buttons()#

Enable or disable the undo/redo buttons based on command history.

class CrocoDash.vgrid_creator.VGridCreator(*args: t.Any, **kwargs: t.Any)#

Bases: HBox

Interactive creator for vertical grids (VGrid). Allows creation, editing, saving, and loading of vertical grid profiles.

Next step#

Once you have your Grid, Topo, and VGrid objects ready, pass them to the Case object to move on to Case Setup:

case = cd.Case(
    ocn_grid=grid,
    ocn_topo=topo,
    ocn_vgrid=vgrid,
    ...
)

See also#