Release notes#
v4.0.0 (unreleased)#
Breaking Changes#
The underlying data allowing self attration and loading (SAL) correction to tidal forcing has been updated for accuracy, and was derived from the TPXO10v2a datasets. This is not a functional breaking change, but will change (improve) output from
TidalForcingbased on TPXO data compared to previos versions of ROMS-Tools. See (#617)ERA5 data correction in
SurfaceForcingnow includes longwave radiation, and the shortwave radiation correction multipliers are updated (#614). This is a breaking change only in the sense that input radiation fields generated by ROMS-Tools using ERA5 forcing data will be slightly different (but more correct) compared to previous ROMS-Tools versions. Correction factors for previous versions of ROMS-Tools remain functional and available.pco2 is no longer read in during
SurfaceForcingtype='bgc'(#608).BoundaryForcing’sapply_2d_horizontal_fillargument is deprecated in favor of the newprefillargument (apply_2d_horizontal_fill=True→prefill="2d_lateral_fill",False→prefill=None); it still works but emits aDeprecationWarning. Note thatprefill="2d_lateral_fill"now regrids with the default"auto"engine (xESMF when installed), so its output differs slightly from the pre-v4 AMG+scipy path; passregrid_method="scipy"to reproduce the legacy output byte-for-byte. (#616).SurfaceForcingnow regrids horizontally with the same NaN-aware approach asBoundaryForcingby default (all types —physics,bgc,restoring): masked xESMF bilinear regridding plus inverse-distance-weighted extrapolation (nearest-neighbor pre-fill + scipy linear interpolation fallback when xESMF is unavailable), replacing the AMG Poisson 2D fill + scipy interpolation. Output shifts slightly for users on the defaults; passprefill="2d_lateral_fill", regrid_method="scipy"to reproduce the legacy output. On the default extrapolating path, a ROMS grid that extends beyond the source data coverage now raises a clear coverage error rather than being silently extrapolated. (#629)from_fileis now a private function toGrid. Files are now loaded asGrid(filename='grid.nc')(#573)The
ChildGridhas been removed. Both a child and parent grid are created usingGrid, and the functionsalign_gridsandmake_edataare called to adjust bathymetry and do the mapping (#573).Default river/CDR tracer concentrations are now read from
river_tracer_defaults.ncand differ from the previous hardcoded values (e.g. DIC, NO3, ALK, temperature) (#615)CDR metrics on
ds_cdrrename efficiency fields:cdr_efficiencytocdr_efficiency_from_flux, andcdr_efficiency_from_delta_difftocdr_efficiency_from_DIC_difference. Saved datasets, ensemble inputs, or downstream code using the old names need updating. (#591)CDR ensemble statistics on
Ensemble.dsrename efficiency fields:ensemble_meantoensemble_efficiency_meanandensemble_stdtoensemble_efficiency_std(#591).Drop support for Python 3.11.
New Features#
SurfaceForcingwas refactored to be more dask-lazy, such that data loading/streaming is minimized untilsaveis called on the class, and thereby supports longer periods between start/end dates.SurfaceForcingwithtype='bgc'has new data source option of ‘MBL_co2’ for time-varying co2; climatology no longer acceptd for xco2. (#608)Density-space vertical interpolation for BGC tracers in
InitialConditionsandBoundaryForcingvia the newbgc_interpolation_method="density"option. The source density coordinate is built from the BGC dataset’s own temperature/salinity (the unified dataset providestemp_WOA/salt_WOA). The target density uses the model’s temperature/salinity: forInitialConditionsthis is the physics already in the same object, while forBoundaryForcingthe physicsBoundaryForcingmust be passed asphysics_forcing=. When a BGC source lacks temperature/salinity (e.g. CESM), interpolation falls back to depth space. A densityBoundaryForcing’sphysics_forcingcompanion is now embedded in and restored from its YAML, soto_yaml/from_yamlround-trips preserve density-space interpolation instead of silently falling back to depth (#620).BGC tracer vertical interpolation is now selected via a
bgc_interpolation_methodstring parameter onInitialConditionsandBoundaryForcing, accepting"depth"(default),"density", or"density_mld". The new"density_mld"method identifies the mixed layer depth (MLD) in the source and target density fields (potential density exceeding the surface value by 0.03 kg/m³, the xromsmldconvention); the source mixed layer is scaled so its MLD matches the target’s, and below the MLD the tracer is interpolated 1:1 in depth. This keeps the source and target mixed layers aligned while preserving the absolute depth of sub-mixed-layer features, and avoids the surface degeneracy of pure density-space interpolation. ForBoundaryForcing, the physics temperature/salinity that define the target density coordinate are sampled at the nearest time to each BGC record (sufficient given the climatological output cadence and ROMS’ linear-in-time boundary interpolation), which avoids loading the full physics time series into memory. (#626)make_edatachanged tomake_nesting_infoto_yamlandfrom_yamlwere adjusted to handle child grids after they’ve been modified (#573)Nesting now supports optional baroclinic pressure fluxes via metadata (#568)
Include time records strictly outside start/end bounds for
SurfaceForcing,BoundaryForcing(#547)Nesting operations now infer open boundaries from the mask by default and supports optional BGC boundary outputs via metadata (#550)
Memory savings and speedup for vertical regridding in
InitialConditionsandBoundaryForcing(#528)Potential memory savings and speedup for reading of optimally-chunked netcdf source data files in
InitialConditions,BoundaryForcing, andSurfaceForcing(#572)Option to automatically close narrow 1-cell water channels during mask generation via
Grid.update_mask(close_narrow_channels=True)orGrid(close_narrow_channels=True); integrated into the standard mask workflowBoundaryForcingnow regrids horizontally with a NaN-aware approach by default, removing the need for the slow and memory-hungry 2D Poisson horizontal fill on large multi-year domains. When xESMF is available, masked bilinear regridding (weights renormalized over valid ocean cells) plus inverse-distance-weighted extrapolation (configurable via theextrap_method/extrap_kwargsarguments) produces NaN-free boundaries directly. When xESMF is unavailable (e.g. Windows/pip installs), a nearest-neighbor pre-fill of the source followed by scipy linear interpolation provides an equivalent NaN-free fallback. Note: boundary values shift slightly compared to previous releases for users on the default settings. (#616)BoundaryForcinggains a unifiedprefillargument (withprefill_kwargs) to optionally fill the source before regridding:None(default, no prefill),"2d_lateral_fill"(legacy AMG Poisson fill),"inverse_dist"/"nearest_s2d"(xESMF source-on-source fills), or"nearest_neighbor"(cheap scipy distance-transform fill; also the automatic fallback when xESMF is unavailable). The horizontal regrid engine is now selected independently viaregrid_method("auto"(default; xESMF if installed else scipy),"xesmf", or"scipy"). (#616)New
typeis added to SurfaceForcing.restoringcreates restoring forces files for ROMS (‘sss’ is the only option) (#589)CDRForcinghas an optiontime_interpolationto choose step-like or interpolated releases (#601)RiverForcingsupports time-varying river BGC from the RIVR2O export product viabgc_source={"name": "RIVR2O", "path": ...}; MARBL tracers not supplied dynamically are filled frombgc_source["fill"](default: recommended constants fromriver_tracer_defaults.nc) (#615)RIVR2O concentrations vary by calendar year and are discharge-partitioned when rivers share a grid cell; missing annual files are linearly interpolated on the year axis (#615)
CDR metrics report CO2 uptake as mass in tonnes of CO2 for both the air-sea flux-difference and DIC-difference constructions (using CO2 molar mass and native flux or inventory units when available). (#591)
The CDR metrics figure from
ROMSOutput.cdr_metrics()uses twin y-axes: CDR efficiency (dimensionless) and CO2 uptake (tonnes CO2), with title “CO2 uptake and CDR efficiency”. (#591)SurfaceForcingwithtype='restoring'now allows for making DIC and ALK restoring forces files (#619)SurfaceForcinggains the same regrid/prefill controls asBoundaryForcing(all types):regrid_method("auto"(default; xESMF if installed else scipy),"xesmf","scipy"),prefill(withprefill_kwargs;Nonedefault = no source fill, or"2d_lateral_fill"/"nearest_neighbor"/"inverse_dist"/"nearest_s2d"/"creep_fill"), andextrap_method(withextrap_kwargs) for the default no-prefill path. These are recorded in the saved dataset metadata and round-trip throughto_yaml/from_yaml. (#XXX)SurfaceForcingwithcorrect_radiation=Truenow scales to long (multi-year) records: the ERA5 radiation-correction climatology is interpolated onto the forcing time axis in chunks, so the correction no longer materializes the full(time, y, x)field at once. This also keeps per-timestep access (e.g. validation) cheap. (#629)New “Downloading ERA5 data” section in the datasets documentation shows how to pre-save ERA5 surface forcing (one file per day, NetCDF or Zarr) from the analysis-ready ARCO cloud store for offline/local use. (#629)
Added support for the GloFAS v4.0 global river discharge dataset as an alternative to Dai & Trenberth, along with performance improvements and bug fixes to the river forcing pipeline. (#625)
The end-to-end example notebook can now be downloaded as a plain Python script from the docs (#630)
Internal Changes#
A function to create a dict from a
Gridobj (#573)A function to check if child wet points are outside the parent (#573)
ChildGridtests were adapted to the new framework (#573)Regression tests for
ChildGrid(#550)Consolidate vertical regridding objects (#528)
Enforce
int32type onChildGridmask (#559)Ensure
regionmask>=0.11.0inpyproject.toml(#565)Integrate narrow-channel closing directly into
Grid.update_mask()(internal_close_narrow_channels), iterating north–south and east–west up to 10 passesshort and long wave radiation time is shifted 1/2 a timestep sooner and have a dim of
rad_time(#586)The coarse UNIFIED BGC dataset used for testing was updated to have depths of 0 and 5 m available (#589)
2 checks added for a point source when plotting
CDRForcing.plot_distribution(). Low hsc is treated as a point source (#600)River BGC refactored behind a
RiverBGCDatasetprotocol;RiverForcingmerges dynamic and fill tracers viafill_river_bgc_concentrations(#615)Rivr2oRiverBGCDatasethandles yearly file loading, spatial sampling, export-to-concentration conversion, and MARBL tracer mapping (#615)Monthly discharge climatology is expanded to calendar mid-month dates when combined with year-indexed RIVR2O BGC (
expand_monthly_climatology_time_axis) (#615)CDR analysis tests cover tonnes-CO2 uptake and renamed efficiency fields;
compute_cdr_metricsrequiresDIC_sourcein the input dataset alongside other CDR variables. (#591)
Documentation#
Nesting notebook is updated to match refactoring of
ChildGridtoGridobjects. (#573)Move “overview of ROMS-Tools functionality” section from paper to docs (#554)
Document
close_narrow_channelsoption inGridandupdate_mask(); update notebook examplesThe boundary forcing notebook is updated to describe the new NaN-aware horizontal regridding (masked bilinear with inverse-distance extrapolation), replacing the previous “1D versus 2D horizontal fill” discussion, and adds a section comparing the
prefillsource-fill methods (2d_lateral_fill,inverse_dist,nearest_s2d,nearest_neighbor) with a strategy table and side-by-side plots of the pre-filled source.Both the surface forcing and datasets notebooks are updated to reflect
restoringfunction and WOA data (#589)The cdr notebook is updated to reflect interpolation option. Default is same as ROMS, no interpolation (#601)
river_forcing.ipynbdocuments RIVR2O BGC forcing, including climatological discharge with year-varying tracers (#615)CDR analysis notebook: describe CO2 uptake (tonnes CO2) and CDR efficiency together, consistent with the metrics and figure. (#591)
Notebooks updated to document density-space BGC interpolation (#620)
Remove example support for CESM data. Boundary, Surface, Initial. (#633)
Added subchunking example code and information on new datasets docs page. (#627)
Bugfixes#
Rotate ROMS velocities before regridding (#522)
Corrected enclosed-basin filling in mask generation by iterating connected-component labels
1..nregin_fill_enclosed_basins, preventing spurious interior lakes; updated the enclosed-region test to expect a single connected wet region.Corrected enclosed-basin filling in mask generation by iterating connected-component labels
1..nregin_fill_enclosed_basins, preventing spurious interior lakes; updated the enclosed-region test to expect a single connected wet region. (#577)Fix timer logging messages during mask generation so durations render correctly when closing narrow channels and filling enclosed basins
Fix for hanging when using the default of streaming from Copernicus for GLORYS output. (#604)
Fix for river forcing indexing, sorting and plotting so that river_forcing.plot() and river_forcing.plot_locations() correctly shows top 20 largest rivers when plotting.
v3.5.0#
New Features#
Initialize inner-nest initial conditions from outer-nest ROMS restart file (#513)
v3.4.0#
New Features#
Breaking Changes#
Remove user-facing control of SSH-adjusted depth coordinates (
adjust_depth_for_sea_surface_heightparameter) forInitialConditionsandBoundaryForcing, enforcing consistent and physically sensible defaults (#514)Remove
horizontal_chunk_sizeparameter fromInitialConditions; the new vertical regridding scheme is sufficiently memory-efficient without it (#528)
Internal Changes#
Bugfixes#
v3.3.0#
New Features#
Internal Changes#
Documentation#
Document support for child grids that extend beyond parent grids (#491)
Bugfixes#
v3.2.0#
New Features#
Enhance
partition_netcdfflexibility: now supports partitioning multiple input files and allows specifying a custom output directory for saved tiles (#394)Add
join_netcdffunction: users can now re-join ROMS output and partitioned files (#412)Option to plot bathymetry along fixed lat/lon section (#399)
Truly centered Gaussian CDR releases, reflecting recent changes in ucla-roms (#413)
Introduce GLORYS streaming support for
InitialConditionsusing copernicusmarine — not recommended yet; performance remains a blocker (#424)Allow performing CDR analysis, including plotting CDR uptake curves (#417)
Introduce parameter
allow_flex_timeforInitialConditionscontrolling how strictlyini_timeis handled (#460)Add utility function
get_glorys_boundsto return the min/max latitude and longitude required for GLORYS downloads for a fixed domain (#445)Add
compute_total_cdr_sourcemethod toCDRForcing, which computes integrated tracer quantities for all releases and returns a pandas DataFrame including a units row (#444)Plot ensembles of CDR uptake curves and their mean and standard deviation (#467)
Allow custom shapefiles (such as GSHHS) to be used for coastline masking (#475)
Breaking Changes#
Default of new
allow_flex_timeparameter forInitialConditionsis set toFalse. Old behaviour wasallow_flex_time = True. (#460)
Documentation#
Add an end-to-end example to help users run through the full workflow (#468)
Bugfixes#
v3.1.2#
New Features#
Enhance
partition_netcdfflexibility: now supports partitioning multiple input files and allows specifying a custom output directory for saved tiles (#394)Option to plot bathymetry along fixed lat/lon section (#399)
Truly centered Gaussian CDR releases, reflecting recent changes in ucla-roms (#413)
Internal Changes#
Require xgcm version >= 0.9.0 (#425)
Documentation#
v3.1.1#
Internal Changes#
Add zarr as optional dependency (#393)
v3.1.0#
New Features#
Allow plotting of a selected subset of river locations or time series, using the
river_namesargument (#389)Limit plotting to a maximum of 20 rivers/CDR forcings to match colormap constraints, with a warning if more are provided (#389)
A unified
plotfunction is now available, enabling users to create custom plots more easily (#375)
from roms_tools.plot import plot
plot(field, grid.ds)
Gaussian CDR plots replicate the internal behavior of ROMS more accurately (#379)
Section plots now include gray topography shading (#379)
Grid latitude/longitude generation is updated to match UCLA MATLAB tools (#381)
Bathymetry smoothing is modified by reducing the smoothing scale and applying an area-weighted scheme (#381)
Remove cartopy coastlines from plots for the sake of clarity (#387)
Breaking Changes#
Grid.plot()no longer accepts thebathymetryargument. Bathymetry is now always plotted by default. (#375)
Internal Changes#
Documentation#
Bugfixes#
Prevent plotting errors when more than 20 CDR or river forcings are present (#389)
Fix bug incorrectly identifying CDR releases as outside the domain (#377)
Add a de-duplication step that ensures that river names are unique (#378)
Grid boundary plotting now provides a more accurate and consistent visual representation, with a default edge color of black. (#375)
Handle overlapping rivers correctly (#356)
v3.0.0#
New Features#
Visualize Gaussian distribution associated with CDR releases (#345)
Make
Grid.from_file()more robust for non-ROMS-Tools-generated grids (#365)Optimize wind drop-off calculation to avoid out-of-memory errors (#367)
Option to stream ERA5 data directly from the cloud so that users do not have to pre-download ERA5 data (#357)
Option for wind drop-off near the coasts in
SurfaceForcing(#351)Option to ignore coarse dimensions when partitioning (#348)
Ensure clean initialization of
SurfaceForcingwith ERA5 data (no warnings) (#337)Handle duplicate time entries in source data (#336)
Set BGC tracers in rivers to non-zero default values (#326)
Add
.get_tracer_metadata()method toVolumeReleaseandTracerPerturbationto allow users to inspect expected tracer units ahead of time (#327)Include tracer units in CDR forcing YAML files (#327)
Add
CDRForcingas a unified interface for CDR releases with and without volume flux (#301)Introduce
TracerPerturbationfor tracer-only CDR scenarios (#301)Add
.plot_tracer_flux()method for visualizing tracer flux time series (#301)Allow bigger grid sizes of up to 25000 km (#311)
Allow larger bottom control parameter
theta_bup to 10 (#317)
Breaking Changes#
Internal Changes#
Introduce Pydantic
Releaseobject refactoring theCDRVolumePointSource(#298)Add zero padding to
partition_netcdffile numbers in filenames (#300)Refactor
Releaseinto its own module with subclassing (VolumeRelease,TracerPerturbation) (#301)Add new core classes:
ReleaseSimulationManager,ReleaseCollector, andCDRForcingDatasetBuilder(#301)
Documentation#
Bugfixes#
Fix plotting
ROMSOutputfor grids that straddle the dateline (#347)Report topography source path in NetCDF grid file so that the sequence
Grid.from_file()–>grid.to_yaml()works (#353)Fix bug related to passing an
axto plotting methods (#325)Fix bug for
grid = Grid.from_file()–>grid.to_yaml()sequence (#334)Fix handling of optional variables in Unified BGC datasets (#320)
v2.7.0#
New Features#
New class
CDRVolumePointSourcefor creating Carbon Dioxide Removal (CDR) forcing in ROMS simulations. It supports point-source injection of water and BGC tracers at fixed locations, designed for field-scale deployments, where localized mixing is essential (#295)TidalForcingclass now works with original (rather than postprocessed) TPXO data (#254)
Breaking Changes#
TidalForcingclass now expects original (rather than postprocessed) TPXO data. See documentation for details. (#254)
Internal Changes#
Correct default value for NOx from 1e-13 to 1e-12 kg/m2/s (#294)
The
TidalForcingclass now correctly handles staggered grid of TPXO data (#254)The
TidalForcingclass now includes enhanced and more robust constituent correction, making it compatible with newer TPXO products (#254)The Self-Attraction and Loading (SAL) correction for the tidal forcing is sourced internally from the TPXO09v2a dataset since it is not included in the regularly updated TPXO datasets (#254)
Documentation#
Updated documentation for the
TidalForcingclass and its dataset requirements (#254)
v2.6.2#
New Features#
Enable reading from unified BGC dataset (#274)
Internal Changes#
Refactoring of
InitialConditions,BoundaryForcing, andSurfaceForcingto accommodate optional variable names (#274)Modification of the
Datasetclass including thechoose_subdomainmethod, the capability to handle fractional days in a climatology, and the addition of aneeds_lateral_fillattribute (#274)Separation of
river_fluxvariable intoriver_indexandriver_fraction(#291)
v2.6.1#
New Features#
Support to regrid ROMS output data onto lat-lon-z grid (#286)
Internal Changes#
Rename
river_locationtoriver_flux(#283)
Bugfixes#
v2.6.0#
New Features#
Internal Changes#
v2.5.0#
New Features#
Support for creating multi-cell rivers (#258)
Support for writing and reading single-cell and multi-cell rivers to/from YAML (#258)
Enable plotting ROMS output without boundary; helpful because boundary for ROMS diagnostics consists of zeros (#265)
Nicer y-labels for depth plots (#265)
Option to enable or disable adjusting for SSH in depth coordinate calculation for
ROMSOutput(#269)
Breaking Changes#
Internal Changes#
Enforce double precision on source data to ensure reproducible results (#244)
Results produced with vs. without Dask in test suite now pass with
xr.testing.assert_equalconfirming reproducibility (#244)Document the option for
start_time = Noneandend_time = Nonein the docstrings forBoundaryForcingandSurfaceForcing, specifying that when both areNone, no time filtering is applied to the data. Also, ensure a warning is raised in this case to inform the user. (#249)Move conversion to double precision to after choosing subdomain of source data, ensuring a speed-up in grid generation and other forcing datasets that do not use Dask (#264)
Documentation#
Bugfixes#
v2.4.0#
New Features#
Introduce new parameter
coarse_grid_modeforSurfaceForcing. The defaultcoarse_grid_mode = "auto"automatically decides whether it makes sense to interpolate onto the coarse grid, which saves computations (#228)New default for
correct_radiationinSurfaceForcingisTrue(#228)New default for
bathymetryinGrid.plot()isTrue(#234)New default for
groupinSurfaceForcing.save()andBoundaryForcing.save()isTrue(#236)Option to adjust depth for sea surface height when creating
InitialConditionsandBoundaryForcing(#240)New parameter
horizontal_chunk_sizeforInitialConditions, which ensures the feasibility of processing initial conditions for large domains, both in terms of memory footprint and compute times (#241)
Breaking Changes#
Internal Changes#
Parallelize computation of radiation correction, leading to a hugely improved memory footprint for surface forcing generation (#227)
For computation of radiation correction, swap order of temporal and spatial interpolation to further improve memory footprint (#227)
Write river locations into river forcing file rather than into grid file (#232)
When appropriate, only compare data hashes rather than file hashes in automated test suite (#235)
Slightly shift one of the test grids away from the Greenwich meridian (#235)
The partitioning functions are moved to their own subdirectory
tiling(#236)Internal refactoring of depth coordinate computation (#240)
Documentation#
New features and defaults are documented for
SurfaceForcing((#228)Improvements to the notebook that documents the partioning functionality (#236)
Document the option to adjust depth for sea surface height (#240)
More realistic, higher-resolution domains in the example notebooks, which use the SRTM15 topography to discourage the user from employing the default ETOPO5 topography (#241)
Bugfixes#
Fix bug in validation step for surface forcing (#227)
v2.3.0#
New Features#
ROMSOutputclass for analyzing ROMS model output (#217)
Bugfixes#
Correctly handle list of files in
sourceandbgc_sourcein YAML files (#218)
v2.2.1#
Bugfixes#
Correctly write Pathlib
bgc_sourceto YAML file (#215)
v2.2.0#
Bugfixes#
v2.1.0#
New Features#
Internal Changes#
Dirty tagging in the versioning has been removed (#202).
Documentation#
Release notes have been added to the documentation (#202).
Bugfixes#
Bug with radiation correction in surface forcing has been fixed (#209).
v2.0.0#
New Features#
Breaking Changes#
The topography format is no longer backward compatible. The syntax for specifying the topography source has changed (#172). The new format is
grid = Grid(topography_source={"name": "ETOPO5"})
instead of the previous format
grid = Grid(topography_source="ETOPO5")
Internal Changes#
Topography regridding function has been generalized (#172).
The classes
roms_tools.setup.datasets.ETOPO5Datasetandroms_tools.setup.datasets.SRTM15Datasethave been introduced (#172).The
roms_tools.setup.datasets.Datasetclass has been made more performant byensuring that global datasets are only concatenated along the longitude dimension when necessary and
restricting to the necessary latitute range first before concatenation (#172).
Layer and interface depths are not computed as part of grid generation any longer because this can blow memory for large domains. Instead, layer and interface depths are only computed when needed as part of initial conditions and boundary forcing generation (#172).
Documentation#
SRTM15 topography examples have been added to the documentation (#172).