roms-tools 1.6.2__py3-none-any.whl → 2.0.0__py3-none-any.whl
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.
- ci/environment.yml +1 -1
- roms_tools/__init__.py +1 -0
- roms_tools/_version.py +1 -1
- roms_tools/setup/boundary_forcing.py +266 -256
- roms_tools/setup/datasets.py +986 -231
- roms_tools/setup/download.py +41 -15
- roms_tools/setup/grid.py +561 -512
- roms_tools/setup/initial_conditions.py +162 -106
- roms_tools/setup/mask.py +69 -0
- roms_tools/setup/plot.py +81 -23
- roms_tools/setup/regrid.py +4 -2
- roms_tools/setup/river_forcing.py +589 -0
- roms_tools/setup/surface_forcing.py +21 -130
- roms_tools/setup/tides.py +15 -79
- roms_tools/setup/topography.py +92 -128
- roms_tools/setup/utils.py +307 -25
- roms_tools/setup/vertical_coordinate.py +5 -16
- roms_tools/tests/test_setup/test_boundary_forcing.py +10 -7
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zmetadata +157 -130
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/abs_time/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/bry_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/month/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/month/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/month/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +39 -12
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/abs_time/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/dust/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/dust_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/month/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/month/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/month/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +0 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +56 -201
- roms_tools/tests/test_setup/test_data/grid.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/Cs_w/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/{interface_depth_rho → sigma_r}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_r/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_r/0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/{interface_depth_u → sigma_w}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_w/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_w/0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +1 -2
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +58 -203
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/Cs_w/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/mask_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid.zarr/interface_depth_v → grid_that_straddles_dateline.zarr/sigma_r}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_r/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_r/0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid.zarr/layer_depth_rho → grid_that_straddles_dateline.zarr/sigma_w}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_w/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_w/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/.zattrs +3 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/.zgroup +3 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/.zmetadata +214 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/abs_time/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/abs_time/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/abs_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/month/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/month/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/month/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_name/.zarray +24 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_name/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_name/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_time/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_time/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid.zarr/layer_depth_v → river_forcing.zarr/river_tracer}/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_tracer/.zattrs +10 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_tracer/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_volume/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_volume/.zattrs +9 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_volume/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid.zarr/layer_depth_u → river_forcing.zarr/tracer_name}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/tracer_name/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/tracer_name/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zgroup +3 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zmetadata +185 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/abs_time/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/abs_time/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/abs_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_name/.zarray +24 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_name/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_name/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_time/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_time/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid_that_straddles_dateline.zarr/interface_depth_v → river_forcing_no_climatology.zarr/river_tracer}/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_tracer/.zattrs +10 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_tracer/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_volume/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_volume/.zattrs +9 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_volume/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/{grid_that_straddles_dateline.zarr/interface_depth_u → river_forcing_no_climatology.zarr/tracer_name}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/tracer_name/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/tracer_name/0 +0 -0
- roms_tools/tests/test_setup/test_grid.py +110 -12
- roms_tools/tests/test_setup/test_initial_conditions.py +2 -3
- roms_tools/tests/test_setup/test_river_forcing.py +367 -0
- roms_tools/tests/test_setup/test_surface_forcing.py +2 -24
- roms_tools/tests/test_setup/test_tides.py +2 -3
- roms_tools/tests/test_setup/test_topography.py +106 -1
- roms_tools/tests/test_setup/test_validation.py +4 -0
- roms_tools/utils.py +12 -10
- {roms_tools-1.6.2.dist-info → roms_tools-2.0.0.dist-info}/LICENSE +1 -1
- {roms_tools-1.6.2.dist-info → roms_tools-2.0.0.dist-info}/METADATA +6 -5
- {roms_tools-1.6.2.dist-info → roms_tools-2.0.0.dist-info}/RECORD +254 -225
- {roms_tools-1.6.2.dist-info → roms_tools-2.0.0.dist-info}/WHEEL +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_vertical_coordinate.py +0 -91
- {roms_tools-1.6.2.dist-info → roms_tools-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import xarray as xr
|
|
2
2
|
import numpy as np
|
|
3
|
-
import yaml
|
|
4
3
|
import importlib.metadata
|
|
5
|
-
from dataclasses import dataclass, field
|
|
4
|
+
from dataclasses import dataclass, field
|
|
6
5
|
from typing import Dict, Union, List, Optional
|
|
7
6
|
from roms_tools.setup.grid import Grid
|
|
8
7
|
from datetime import datetime
|
|
9
8
|
from roms_tools.setup.datasets import GLORYSDataset, CESMBGCDataset
|
|
9
|
+
from roms_tools.setup.vertical_coordinate import compute_depth
|
|
10
10
|
from roms_tools.setup.utils import (
|
|
11
11
|
nan_check,
|
|
12
12
|
substitute_nans_by_fillvalue,
|
|
@@ -16,6 +16,10 @@ from roms_tools.setup.utils import (
|
|
|
16
16
|
rotate_velocities,
|
|
17
17
|
compute_barotropic_velocity,
|
|
18
18
|
transpose_dimensions,
|
|
19
|
+
interpolate_from_rho_to_u,
|
|
20
|
+
interpolate_from_rho_to_v,
|
|
21
|
+
_to_yaml,
|
|
22
|
+
_from_yaml,
|
|
19
23
|
)
|
|
20
24
|
from roms_tools.setup.regrid import LateralRegrid, VerticalRegrid
|
|
21
25
|
from roms_tools.setup.plot import _plot, _section_plot, _profile_plot, _line_plot
|
|
@@ -91,23 +95,17 @@ class InitialConditions:
|
|
|
91
95
|
self._input_checks()
|
|
92
96
|
|
|
93
97
|
processed_fields = {}
|
|
94
|
-
processed_fields
|
|
95
|
-
processed_fields, type="physics"
|
|
96
|
-
)
|
|
98
|
+
processed_fields = self._process_data(processed_fields, type="physics")
|
|
97
99
|
|
|
98
100
|
if self.bgc_source is not None:
|
|
99
|
-
processed_fields
|
|
100
|
-
processed_fields, type="bgc"
|
|
101
|
-
)
|
|
101
|
+
processed_fields = self._process_data(processed_fields, type="bgc")
|
|
102
102
|
|
|
103
103
|
d_meta = get_variable_metadata()
|
|
104
104
|
ds = self._write_into_dataset(processed_fields, d_meta)
|
|
105
105
|
|
|
106
106
|
ds = self._add_global_metadata(ds)
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
variable_info = {**variable_info, **bgc_variable_info}
|
|
110
|
-
self._validate(ds, variable_info)
|
|
108
|
+
self._validate(ds)
|
|
111
109
|
|
|
112
110
|
# substitute NaNs over land by a fill value to avoid blow-up of ROMS
|
|
113
111
|
for var_name in ds.data_vars:
|
|
@@ -132,7 +130,9 @@ class InitialConditions:
|
|
|
132
130
|
data.extrapolate_deepest_to_bottom()
|
|
133
131
|
data.apply_lateral_fill()
|
|
134
132
|
|
|
135
|
-
|
|
133
|
+
self._set_variable_info(data, type=type)
|
|
134
|
+
attr_name = f"variable_info_{type}"
|
|
135
|
+
variable_info = getattr(self, attr_name)
|
|
136
136
|
var_names = variable_info.keys()
|
|
137
137
|
|
|
138
138
|
# lateral regridding
|
|
@@ -152,19 +152,31 @@ class InitialConditions:
|
|
|
152
152
|
interpolate=True,
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
var_names_dict = {}
|
|
156
156
|
for location in ["rho", "u", "v"]:
|
|
157
|
-
|
|
157
|
+
var_names_dict[location] = [
|
|
158
158
|
name
|
|
159
159
|
for name, info in variable_info.items()
|
|
160
160
|
if info["location"] == location and info["is_3d"]
|
|
161
161
|
]
|
|
162
|
-
|
|
162
|
+
|
|
163
|
+
# compute layer depth coordinates
|
|
164
|
+
if len(var_names_dict["u"]) > 0 or len(var_names_dict["v"]) > 0:
|
|
165
|
+
self._get_vertical_coordinates(
|
|
166
|
+
type="layer",
|
|
167
|
+
additional_locations=["u", "v"],
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
if len(var_names_dict["rho"]) > 0:
|
|
171
|
+
self._get_vertical_coordinates(type="layer", additional_locations=[])
|
|
172
|
+
# vertical regridding
|
|
173
|
+
for location in ["rho", "u", "v"]:
|
|
174
|
+
if len(var_names_dict[location]) > 0:
|
|
163
175
|
vertical_regrid = VerticalRegrid(
|
|
164
176
|
self.grid.ds[f"layer_depth_{location}"],
|
|
165
177
|
data.ds[data.dim_names["depth"]],
|
|
166
178
|
)
|
|
167
|
-
for var_name in
|
|
179
|
+
for var_name in var_names_dict[location]:
|
|
168
180
|
if var_name in processed_fields:
|
|
169
181
|
processed_fields[var_name] = vertical_regrid.apply(
|
|
170
182
|
processed_fields[var_name]
|
|
@@ -172,10 +184,14 @@ class InitialConditions:
|
|
|
172
184
|
|
|
173
185
|
# compute barotropic velocities
|
|
174
186
|
if "u" in variable_info and "v" in variable_info:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
187
|
+
self._get_vertical_coordinates(
|
|
188
|
+
type="interface",
|
|
189
|
+
additional_locations=["u", "v"],
|
|
190
|
+
)
|
|
191
|
+
for location in ["u", "v"]:
|
|
192
|
+
processed_fields[f"{location}bar"] = compute_barotropic_velocity(
|
|
193
|
+
processed_fields[location],
|
|
194
|
+
self.grid.ds[f"interface_depth_{location}"],
|
|
179
195
|
)
|
|
180
196
|
|
|
181
197
|
if type == "bgc":
|
|
@@ -190,7 +206,7 @@ class InitialConditions:
|
|
|
190
206
|
processed_fields[var_name]
|
|
191
207
|
)
|
|
192
208
|
|
|
193
|
-
return processed_fields
|
|
209
|
+
return processed_fields
|
|
194
210
|
|
|
195
211
|
def _input_checks(self):
|
|
196
212
|
|
|
@@ -344,7 +360,84 @@ class InitialConditions:
|
|
|
344
360
|
else:
|
|
345
361
|
variable_info[var_name] = {**default_info, "validate": False}
|
|
346
362
|
|
|
347
|
-
|
|
363
|
+
object.__setattr__(self, f"variable_info_{type}", variable_info)
|
|
364
|
+
|
|
365
|
+
def _get_vertical_coordinates(self, type, additional_locations=["u", "v"]):
|
|
366
|
+
"""Retrieve layer and interface depth coordinates.
|
|
367
|
+
|
|
368
|
+
This method computes and updates the layer and interface depth coordinates. It handles depth calculations for rho points and
|
|
369
|
+
additional specified locations (u and v).
|
|
370
|
+
|
|
371
|
+
Parameters
|
|
372
|
+
----------
|
|
373
|
+
type : str
|
|
374
|
+
The type of depth coordinate to retrieve. Valid options are:
|
|
375
|
+
- "layer": Retrieves layer depth coordinates.
|
|
376
|
+
- "interface": Retrieves interface depth coordinates.
|
|
377
|
+
|
|
378
|
+
additional_locations : list of str, optional
|
|
379
|
+
Specifies additional locations to compute depth coordinates for. Default is ["u", "v"].
|
|
380
|
+
Valid options include:
|
|
381
|
+
- "u": Computes depth coordinates for u points.
|
|
382
|
+
- "v": Computes depth coordinates for v points.
|
|
383
|
+
|
|
384
|
+
Updates
|
|
385
|
+
-------
|
|
386
|
+
self.grid.ds : xarray.Dataset
|
|
387
|
+
The dataset is updated with the following vertical depth coordinates:
|
|
388
|
+
- f"{type}_depth_rho": Depth coordinates at rho points.
|
|
389
|
+
- f"{type}_depth_u": Depth coordinates at u points (if applicable).
|
|
390
|
+
- f"{type}_depth_v": Depth coordinates at v points (if applicable).
|
|
391
|
+
"""
|
|
392
|
+
|
|
393
|
+
layer_vars = []
|
|
394
|
+
for location in ["rho"] + additional_locations:
|
|
395
|
+
layer_vars.append(f"{type}_depth_{location}")
|
|
396
|
+
|
|
397
|
+
if all(layer_var in self.grid.ds for layer_var in layer_vars):
|
|
398
|
+
# Vertical coordinate data already exists
|
|
399
|
+
pass
|
|
400
|
+
|
|
401
|
+
elif f"{type}_depth_rho" in self.grid.ds:
|
|
402
|
+
depth = self.grid.ds[f"{type}_depth_rho"]
|
|
403
|
+
|
|
404
|
+
if "u" in additional_locations or "v" in additional_locations:
|
|
405
|
+
# interpolation
|
|
406
|
+
if "u" in additional_locations:
|
|
407
|
+
depth_u = interpolate_from_rho_to_u(depth)
|
|
408
|
+
depth_u.attrs["long_name"] = f"{type} depth at u-points"
|
|
409
|
+
depth_u.attrs["units"] = "m"
|
|
410
|
+
self.grid.ds[f"{type}_depth_u"] = depth_u
|
|
411
|
+
if "v" in additional_locations:
|
|
412
|
+
depth_v = interpolate_from_rho_to_v(depth)
|
|
413
|
+
depth_v.attrs["long_name"] = f"{type} depth at v-points"
|
|
414
|
+
depth_v.attrs["units"] = "m"
|
|
415
|
+
self.grid.ds[f"{type}_depth_v"] = depth_v
|
|
416
|
+
else:
|
|
417
|
+
h = self.grid.ds["h"]
|
|
418
|
+
if type == "layer":
|
|
419
|
+
depth = compute_depth(
|
|
420
|
+
0, h, self.grid.hc, self.grid.ds.Cs_r, self.grid.ds.sigma_r
|
|
421
|
+
)
|
|
422
|
+
else:
|
|
423
|
+
depth = compute_depth(
|
|
424
|
+
0, h, self.grid.hc, self.grid.ds.Cs_w, self.grid.ds.sigma_w
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
depth.attrs["long_name"] = f"{type} depth at rho-points"
|
|
428
|
+
depth.attrs["units"] = "m"
|
|
429
|
+
self.grid.ds[f"{type}_depth_rho"] = depth
|
|
430
|
+
|
|
431
|
+
if "u" in additional_locations or "v" in additional_locations:
|
|
432
|
+
# interpolation
|
|
433
|
+
depth_u = interpolate_from_rho_to_u(depth)
|
|
434
|
+
depth_u.attrs["long_name"] = f"{type} depth at u-points"
|
|
435
|
+
depth_u.attrs["units"] = "m"
|
|
436
|
+
depth_v = interpolate_from_rho_to_v(depth)
|
|
437
|
+
depth_v.attrs["long_name"] = f"{type} depth at v-points"
|
|
438
|
+
depth_v.attrs["units"] = "m"
|
|
439
|
+
self.grid.ds[f"{type}_depth_u"] = depth_u
|
|
440
|
+
self.grid.ds[f"{type}_depth_v"] = depth_v
|
|
348
441
|
|
|
349
442
|
def _write_into_dataset(self, processed_fields, d_meta):
|
|
350
443
|
|
|
@@ -387,24 +480,29 @@ class InitialConditions:
|
|
|
387
480
|
ds["Cs_w"] = self.grid.ds["Cs_w"]
|
|
388
481
|
|
|
389
482
|
# Preserve absolute time coordinate for readability
|
|
390
|
-
|
|
483
|
+
abs_time = ds["time"]
|
|
484
|
+
attrs = [key for key in abs_time.attrs]
|
|
485
|
+
for attr in attrs:
|
|
486
|
+
del abs_time.attrs[attr]
|
|
487
|
+
abs_time.attrs["long_name"] = "absolute time"
|
|
488
|
+
ds = ds.assign_coords({"abs_time": abs_time})
|
|
391
489
|
|
|
392
490
|
# Translate the time coordinate to days since the model reference date
|
|
393
491
|
model_reference_date = np.datetime64(self.model_reference_date)
|
|
394
492
|
|
|
395
|
-
# Convert the time coordinate to the format expected by ROMS (
|
|
493
|
+
# Convert the time coordinate to the format expected by ROMS (seconds since model reference date)
|
|
396
494
|
ocean_time = (ds["time"] - model_reference_date).astype("float64") * 1e-9
|
|
397
495
|
ds = ds.assign_coords(ocean_time=("time", ocean_time.data.astype("float64")))
|
|
398
496
|
ds["ocean_time"].attrs[
|
|
399
497
|
"long_name"
|
|
400
|
-
] = f"seconds since {str(self.model_reference_date)}"
|
|
498
|
+
] = f"relative time: seconds since {str(self.model_reference_date)}"
|
|
401
499
|
ds["ocean_time"].attrs["units"] = "seconds"
|
|
402
500
|
ds = ds.swap_dims({"time": "ocean_time"})
|
|
403
501
|
ds = ds.drop_vars("time")
|
|
404
502
|
|
|
405
503
|
return ds
|
|
406
504
|
|
|
407
|
-
def _validate(self, ds
|
|
505
|
+
def _validate(self, ds):
|
|
408
506
|
"""Validates the dataset by checking for NaN values in SSH at wet points, which
|
|
409
507
|
would indicate missing raw data coverage over the target domain.
|
|
410
508
|
|
|
@@ -412,8 +510,6 @@ class InitialConditions:
|
|
|
412
510
|
----------
|
|
413
511
|
ds : xarray.Dataset
|
|
414
512
|
The dataset to validate.
|
|
415
|
-
variable_info : dict
|
|
416
|
-
A dictionary containing metadata about the variables, including whether to validate them.
|
|
417
513
|
|
|
418
514
|
Raises
|
|
419
515
|
------
|
|
@@ -425,6 +521,10 @@ class InitialConditions:
|
|
|
425
521
|
-----
|
|
426
522
|
This check is only applied to the 2D variable SSH to improve performance.
|
|
427
523
|
"""
|
|
524
|
+
if self.bgc_source is not None:
|
|
525
|
+
variable_info = {**self.variable_info_physics, **self.variable_info_bgc}
|
|
526
|
+
else:
|
|
527
|
+
variable_info = self.variable_info_physics
|
|
428
528
|
|
|
429
529
|
for var_name in variable_info:
|
|
430
530
|
# Only validate variables based on "validate" flag if use_dask is False
|
|
@@ -564,9 +664,17 @@ class InitialConditions:
|
|
|
564
664
|
self.ds[var_name].load()
|
|
565
665
|
|
|
566
666
|
field = self.ds[var_name].squeeze()
|
|
667
|
+
if s is not None:
|
|
668
|
+
layer_contours = False
|
|
567
669
|
|
|
568
670
|
if all(dim in field.dims for dim in ["eta_rho", "xi_rho"]):
|
|
569
|
-
|
|
671
|
+
if layer_contours:
|
|
672
|
+
if "interface_depth_rho" in self.grid.ds:
|
|
673
|
+
interface_depth = self.grid.ds.interface_depth_rho
|
|
674
|
+
else:
|
|
675
|
+
self.get_vertical_coordinates(
|
|
676
|
+
type="interface", additional_locations=[]
|
|
677
|
+
)
|
|
570
678
|
layer_depth = self.grid.ds.layer_depth_rho
|
|
571
679
|
mask = self.grid.ds.mask_rho
|
|
572
680
|
field = field.assign_coords(
|
|
@@ -574,7 +682,13 @@ class InitialConditions:
|
|
|
574
682
|
)
|
|
575
683
|
|
|
576
684
|
elif all(dim in field.dims for dim in ["eta_rho", "xi_u"]):
|
|
577
|
-
|
|
685
|
+
if layer_contours:
|
|
686
|
+
if "interface_depth_u" in self.grid.ds:
|
|
687
|
+
interface_depth = self.grid.ds.interface_depth_u
|
|
688
|
+
else:
|
|
689
|
+
self.get_vertical_coordinates(
|
|
690
|
+
type="interface", additional_locations=["u", "v"]
|
|
691
|
+
)
|
|
578
692
|
layer_depth = self.grid.ds.layer_depth_u
|
|
579
693
|
mask = self.grid.ds.mask_u
|
|
580
694
|
field = field.assign_coords(
|
|
@@ -582,7 +696,13 @@ class InitialConditions:
|
|
|
582
696
|
)
|
|
583
697
|
|
|
584
698
|
elif all(dim in field.dims for dim in ["eta_v", "xi_rho"]):
|
|
585
|
-
|
|
699
|
+
if layer_contours:
|
|
700
|
+
if "interface_depth_v" in self.grid.ds:
|
|
701
|
+
interface_depth = self.grid.ds.interface_depth_v
|
|
702
|
+
else:
|
|
703
|
+
self.get_vertical_coordinates(
|
|
704
|
+
type="interface", additional_locations=["u", "v"]
|
|
705
|
+
)
|
|
586
706
|
layer_depth = self.grid.ds.layer_depth_v
|
|
587
707
|
mask = self.grid.ds.mask_v
|
|
588
708
|
field = field.assign_coords(
|
|
@@ -606,14 +726,16 @@ class InitialConditions:
|
|
|
606
726
|
title = title + f", eta_rho = {field.eta_rho[eta].item()}"
|
|
607
727
|
field = field.isel(eta_rho=eta)
|
|
608
728
|
layer_depth = layer_depth.isel(eta_rho=eta)
|
|
609
|
-
|
|
729
|
+
if layer_contours:
|
|
730
|
+
interface_depth = interface_depth.isel(eta_rho=eta)
|
|
610
731
|
if "s_rho" in field.dims:
|
|
611
732
|
field = field.assign_coords({"layer_depth": layer_depth})
|
|
612
733
|
elif "eta_v" in field.dims:
|
|
613
734
|
title = title + f", eta_v = {field.eta_v[eta].item()}"
|
|
614
735
|
field = field.isel(eta_v=eta)
|
|
615
736
|
layer_depth = layer_depth.isel(eta_v=eta)
|
|
616
|
-
|
|
737
|
+
if layer_contours:
|
|
738
|
+
interface_depth = interface_depth.isel(eta_v=eta)
|
|
617
739
|
if "s_rho" in field.dims:
|
|
618
740
|
field = field.assign_coords({"layer_depth": layer_depth})
|
|
619
741
|
else:
|
|
@@ -625,14 +747,16 @@ class InitialConditions:
|
|
|
625
747
|
title = title + f", xi_rho = {field.xi_rho[xi].item()}"
|
|
626
748
|
field = field.isel(xi_rho=xi)
|
|
627
749
|
layer_depth = layer_depth.isel(xi_rho=xi)
|
|
628
|
-
|
|
750
|
+
if layer_contours:
|
|
751
|
+
interface_depth = interface_depth.isel(xi_rho=xi)
|
|
629
752
|
if "s_rho" in field.dims:
|
|
630
753
|
field = field.assign_coords({"layer_depth": layer_depth})
|
|
631
754
|
elif "xi_u" in field.dims:
|
|
632
755
|
title = title + f", xi_u = {field.xi_u[xi].item()}"
|
|
633
756
|
field = field.isel(xi_u=xi)
|
|
634
757
|
layer_depth = layer_depth.isel(xi_u=xi)
|
|
635
|
-
|
|
758
|
+
if layer_contours:
|
|
759
|
+
interface_depth = interface_depth.isel(xi_u=xi)
|
|
636
760
|
if "s_rho" in field.dims:
|
|
637
761
|
field = field.assign_coords({"layer_depth": layer_depth})
|
|
638
762
|
else:
|
|
@@ -753,48 +877,8 @@ class InitialConditions:
|
|
|
753
877
|
filepath : Union[str, Path]
|
|
754
878
|
The path to the YAML file where the parameters will be saved.
|
|
755
879
|
"""
|
|
756
|
-
filepath = Path(filepath)
|
|
757
|
-
|
|
758
|
-
# Serialize Grid data
|
|
759
|
-
grid_data = asdict(self.grid)
|
|
760
|
-
grid_data.pop("ds", None) # Exclude non-serializable fields
|
|
761
|
-
grid_data.pop("straddle", None)
|
|
762
|
-
|
|
763
|
-
# Include the version of roms-tools
|
|
764
|
-
try:
|
|
765
|
-
roms_tools_version = importlib.metadata.version("roms-tools")
|
|
766
|
-
except importlib.metadata.PackageNotFoundError:
|
|
767
|
-
roms_tools_version = "unknown"
|
|
768
|
-
|
|
769
|
-
# Create header
|
|
770
|
-
header = f"---\nroms_tools_version: {roms_tools_version}\n---\n"
|
|
771
|
-
|
|
772
|
-
grid_yaml_data = {"Grid": grid_data}
|
|
773
880
|
|
|
774
|
-
|
|
775
|
-
"InitialConditions": {
|
|
776
|
-
"ini_time": self.ini_time.isoformat(),
|
|
777
|
-
"source": self.source,
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
# Include bgc_source if it's not None
|
|
781
|
-
if self.bgc_source is not None:
|
|
782
|
-
initial_conditions_data["InitialConditions"]["bgc_source"] = self.bgc_source
|
|
783
|
-
|
|
784
|
-
initial_conditions_data["InitialConditions"][
|
|
785
|
-
"model_reference_date"
|
|
786
|
-
] = self.model_reference_date.isoformat()
|
|
787
|
-
|
|
788
|
-
yaml_data = {
|
|
789
|
-
**grid_yaml_data,
|
|
790
|
-
**initial_conditions_data,
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
with filepath.open("w") as file:
|
|
794
|
-
# Write header
|
|
795
|
-
file.write(header)
|
|
796
|
-
# Write YAML data
|
|
797
|
-
yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
|
|
881
|
+
_to_yaml(self, filepath)
|
|
798
882
|
|
|
799
883
|
@classmethod
|
|
800
884
|
def from_yaml(
|
|
@@ -815,35 +899,7 @@ class InitialConditions:
|
|
|
815
899
|
An instance of the InitialConditions class.
|
|
816
900
|
"""
|
|
817
901
|
filepath = Path(filepath)
|
|
818
|
-
# Read the entire file content
|
|
819
|
-
with filepath.open("r") as file:
|
|
820
|
-
file_content = file.read()
|
|
821
|
-
|
|
822
|
-
# Split the content into YAML documents
|
|
823
|
-
documents = list(yaml.safe_load_all(file_content))
|
|
824
|
-
|
|
825
|
-
initial_conditions_data = None
|
|
826
|
-
|
|
827
|
-
# Process the YAML documents
|
|
828
|
-
for doc in documents:
|
|
829
|
-
if doc is None:
|
|
830
|
-
continue
|
|
831
|
-
if "InitialConditions" in doc:
|
|
832
|
-
initial_conditions_data = doc["InitialConditions"]
|
|
833
|
-
break
|
|
834
|
-
|
|
835
|
-
if initial_conditions_data is None:
|
|
836
|
-
raise ValueError(
|
|
837
|
-
"No InitialConditions configuration found in the YAML file."
|
|
838
|
-
)
|
|
839
|
-
|
|
840
|
-
# Convert from string to datetime
|
|
841
|
-
for date_string in ["model_reference_date", "ini_time"]:
|
|
842
|
-
initial_conditions_data[date_string] = datetime.fromisoformat(
|
|
843
|
-
initial_conditions_data[date_string]
|
|
844
|
-
)
|
|
845
902
|
|
|
846
903
|
grid = Grid.from_yaml(filepath)
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
return cls(grid=grid, **initial_conditions_data, use_dask=use_dask)
|
|
904
|
+
initial_conditions_params = _from_yaml(cls, filepath)
|
|
905
|
+
return cls(grid=grid, **initial_conditions_params, use_dask=use_dask)
|
roms_tools/setup/mask.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import xarray as xr
|
|
2
|
+
import numpy as np
|
|
3
|
+
import regionmask
|
|
4
|
+
from scipy.ndimage import label
|
|
5
|
+
from roms_tools.setup.utils import (
|
|
6
|
+
interpolate_from_rho_to_u,
|
|
7
|
+
interpolate_from_rho_to_v,
|
|
8
|
+
handle_boundaries,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _add_mask(ds):
|
|
13
|
+
|
|
14
|
+
land = regionmask.defined_regions.natural_earth_v5_0_0.land_10
|
|
15
|
+
|
|
16
|
+
land_mask = land.mask(ds["lon_rho"], ds["lat_rho"])
|
|
17
|
+
mask = land_mask.isnull()
|
|
18
|
+
|
|
19
|
+
# fill enclosed basins with land
|
|
20
|
+
mask = _fill_enclosed_basins(mask.values)
|
|
21
|
+
# adjust mask boundaries by copying values from adjacent cells
|
|
22
|
+
mask = handle_boundaries(mask)
|
|
23
|
+
|
|
24
|
+
ds["mask_rho"] = xr.DataArray(mask.astype(np.int32), dims=("eta_rho", "xi_rho"))
|
|
25
|
+
ds["mask_rho"].attrs = {
|
|
26
|
+
"long_name": "Mask at rho-points",
|
|
27
|
+
"units": "land/water (0/1)",
|
|
28
|
+
}
|
|
29
|
+
ds = _add_velocity_masks(ds)
|
|
30
|
+
|
|
31
|
+
return ds
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _fill_enclosed_basins(mask) -> np.ndarray:
|
|
35
|
+
"""Fills in enclosed basins with land."""
|
|
36
|
+
|
|
37
|
+
# Label connected regions in the mask
|
|
38
|
+
reg, nreg = label(mask)
|
|
39
|
+
# Find the largest region
|
|
40
|
+
lint = 0
|
|
41
|
+
lreg = 0
|
|
42
|
+
for ireg in range(nreg):
|
|
43
|
+
int_ = np.sum(reg == ireg)
|
|
44
|
+
if int_ > lint and mask[reg == ireg].sum() > 0:
|
|
45
|
+
lreg = ireg
|
|
46
|
+
lint = int_
|
|
47
|
+
|
|
48
|
+
# Remove regions other than the largest one
|
|
49
|
+
for ireg in range(nreg):
|
|
50
|
+
if ireg != lreg:
|
|
51
|
+
mask[reg == ireg] = 0
|
|
52
|
+
|
|
53
|
+
return mask
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _add_velocity_masks(ds):
|
|
57
|
+
|
|
58
|
+
# add u- and v-masks
|
|
59
|
+
ds["mask_u"] = interpolate_from_rho_to_u(
|
|
60
|
+
ds["mask_rho"], method="multiplicative"
|
|
61
|
+
).astype(np.int32)
|
|
62
|
+
ds["mask_v"] = interpolate_from_rho_to_v(
|
|
63
|
+
ds["mask_rho"], method="multiplicative"
|
|
64
|
+
).astype(np.int32)
|
|
65
|
+
|
|
66
|
+
ds["mask_u"].attrs = {"long_name": "Mask at u-points", "units": "land/water (0/1)"}
|
|
67
|
+
ds["mask_v"].attrs = {"long_name": "Mask at v-points", "units": "land/water (0/1)"}
|
|
68
|
+
|
|
69
|
+
return ds
|
roms_tools/setup/plot.py
CHANGED
|
@@ -58,16 +58,71 @@ def _plot(
|
|
|
58
58
|
if straddle:
|
|
59
59
|
lon_deg = xr.where(lon_deg > 180, lon_deg - 360, lon_deg)
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
proj = ccrs.PlateCarree()
|
|
63
|
-
|
|
64
|
-
trans = ccrs.NearsidePerspective(
|
|
65
|
-
central_longitude=lon_deg.mean().values, central_latitude=lat_deg.mean().values
|
|
66
|
-
)
|
|
61
|
+
trans = _get_projection(lon_deg, lat_deg)
|
|
67
62
|
|
|
68
63
|
lon_deg = lon_deg.values
|
|
69
64
|
lat_deg = lat_deg.values
|
|
70
65
|
|
|
66
|
+
fig, ax = plt.subplots(1, 1, figsize=(13, 7), subplot_kw={"projection": trans})
|
|
67
|
+
|
|
68
|
+
_add_plot_to_ax(
|
|
69
|
+
ax, lon_deg, lat_deg, trans, field, depth_contours, c, title, kwargs=kwargs
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _add_plot_to_ax(
|
|
74
|
+
ax,
|
|
75
|
+
lon_deg,
|
|
76
|
+
lat_deg,
|
|
77
|
+
trans,
|
|
78
|
+
field=None,
|
|
79
|
+
depth_contours=False,
|
|
80
|
+
c="red",
|
|
81
|
+
title="",
|
|
82
|
+
add_colorbar=True,
|
|
83
|
+
kwargs=None,
|
|
84
|
+
):
|
|
85
|
+
"""Plots a grid or field on a map with optional depth contours.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
ax : matplotlib.axes._axes.Axes
|
|
90
|
+
The axes on which to plot the data (Cartopy axis with projection).
|
|
91
|
+
|
|
92
|
+
lon_deg : np.ndarray
|
|
93
|
+
Longitude values in degrees.
|
|
94
|
+
|
|
95
|
+
lat_deg : np.ndarray
|
|
96
|
+
Latitude values in degrees.
|
|
97
|
+
|
|
98
|
+
trans : cartopy.crs.Projection
|
|
99
|
+
The projection for transforming coordinates.
|
|
100
|
+
|
|
101
|
+
field : xarray.DataArray, optional
|
|
102
|
+
Field data to plot (e.g., temperature, salinity). If None, only the grid is plotted.
|
|
103
|
+
|
|
104
|
+
depth_contours : bool, optional
|
|
105
|
+
If True, adds depth contours to the plot.
|
|
106
|
+
|
|
107
|
+
c : str, optional
|
|
108
|
+
Color of the grid boundary (default is 'red').
|
|
109
|
+
|
|
110
|
+
title : str, optional
|
|
111
|
+
Title of the plot.
|
|
112
|
+
|
|
113
|
+
add_colorbar : bool, optional
|
|
114
|
+
If True, add colobar.
|
|
115
|
+
|
|
116
|
+
kwargs : dict, optional
|
|
117
|
+
Additional keyword arguments passed to `pcolormesh` (e.g., colormap, limits).
|
|
118
|
+
|
|
119
|
+
Notes
|
|
120
|
+
-----
|
|
121
|
+
- If `field` is provided, a colorbar is added.
|
|
122
|
+
- If `depth_contours` is True, the field’s `layer_depth` is used to add contours.
|
|
123
|
+
"""
|
|
124
|
+
proj = ccrs.PlateCarree()
|
|
125
|
+
|
|
71
126
|
# find corners
|
|
72
127
|
corners = [
|
|
73
128
|
(lon_deg[0, 0], lat_deg[0, 0]),
|
|
@@ -80,14 +135,13 @@ def _plot(
|
|
|
80
135
|
transformed_corners = [trans.transform_point(lo, la, proj) for lo, la in corners]
|
|
81
136
|
transformed_lons, transformed_lats = zip(*transformed_corners)
|
|
82
137
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
138
|
+
if c is not None:
|
|
139
|
+
ax.plot(
|
|
140
|
+
list(transformed_lons) + [transformed_lons[0]],
|
|
141
|
+
list(transformed_lats) + [transformed_lats[0]],
|
|
142
|
+
"o-",
|
|
143
|
+
c=c,
|
|
144
|
+
)
|
|
91
145
|
|
|
92
146
|
ax.coastlines(
|
|
93
147
|
resolution="50m", linewidth=0.5, color="black"
|
|
@@ -104,13 +158,21 @@ def _plot(
|
|
|
104
158
|
label = f"{field.Long_name} [{field.units}]"
|
|
105
159
|
else:
|
|
106
160
|
label = ""
|
|
107
|
-
|
|
161
|
+
if add_colorbar:
|
|
162
|
+
plt.colorbar(p, label=label)
|
|
108
163
|
|
|
109
164
|
if depth_contours:
|
|
110
165
|
cs = ax.contour(lon_deg, lat_deg, field.layer_depth, transform=proj, colors="k")
|
|
111
166
|
ax.clabel(cs, inline=True, fontsize=10)
|
|
112
167
|
|
|
113
168
|
|
|
169
|
+
def _get_projection(lon, lat):
|
|
170
|
+
|
|
171
|
+
return ccrs.NearsidePerspective(
|
|
172
|
+
central_longitude=lon.mean().values, central_latitude=lat.mean().values
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
114
176
|
def _section_plot(field, interface_depth=None, title="", kwargs={}, ax=None):
|
|
115
177
|
|
|
116
178
|
if ax is None:
|
|
@@ -176,18 +238,14 @@ def _profile_plot(field, title="", ax=None):
|
|
|
176
238
|
"""
|
|
177
239
|
|
|
178
240
|
depths_to_check = [
|
|
179
|
-
"
|
|
180
|
-
"
|
|
181
|
-
"layer_depth_v",
|
|
182
|
-
"interface_depth_rho",
|
|
183
|
-
"interface_depth_u",
|
|
184
|
-
"interface_depth_v",
|
|
241
|
+
"layer_depth",
|
|
242
|
+
"interface_depth",
|
|
185
243
|
]
|
|
186
244
|
try:
|
|
187
245
|
depth_label = next(
|
|
188
246
|
depth_label
|
|
189
|
-
for depth_label in
|
|
190
|
-
if depth_label in
|
|
247
|
+
for depth_label in field.coords
|
|
248
|
+
if any(depth_label.startswith(prefix) for prefix in depths_to_check)
|
|
191
249
|
)
|
|
192
250
|
except StopIteration:
|
|
193
251
|
raise ValueError(
|
roms_tools/setup/regrid.py
CHANGED
|
@@ -28,20 +28,22 @@ class LateralRegrid:
|
|
|
28
28
|
source_dim_names["longitude"]: target_coords["lon"],
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
def apply(self, da):
|
|
31
|
+
def apply(self, da, method="linear"):
|
|
32
32
|
"""Fills missing values and regrids the variable.
|
|
33
33
|
|
|
34
34
|
Parameters
|
|
35
35
|
----------
|
|
36
36
|
da : xarray.DataArray
|
|
37
37
|
Input data to fill and regrid.
|
|
38
|
+
method : str
|
|
39
|
+
Interpolation method to use.
|
|
38
40
|
|
|
39
41
|
Returns
|
|
40
42
|
-------
|
|
41
43
|
xarray.DataArray
|
|
42
44
|
Regridded data with filled values.
|
|
43
45
|
"""
|
|
44
|
-
regridded = da.interp(self.coords, method=
|
|
46
|
+
regridded = da.interp(self.coords, method=method).drop_vars(
|
|
45
47
|
list(self.coords.keys())
|
|
46
48
|
)
|
|
47
49
|
return regridded
|