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,16 +1,15 @@
|
|
|
1
1
|
import xarray as xr
|
|
2
2
|
import numpy as np
|
|
3
|
-
import pandas as pd
|
|
4
3
|
from scipy.ndimage import label
|
|
5
4
|
import logging
|
|
6
|
-
import yaml
|
|
7
5
|
import importlib.metadata
|
|
8
6
|
from typing import Dict, Union, List
|
|
9
|
-
from dataclasses import dataclass, field
|
|
7
|
+
from dataclasses import dataclass, field
|
|
10
8
|
from roms_tools.setup.grid import Grid
|
|
11
9
|
from roms_tools.setup.regrid import LateralRegrid, VerticalRegrid
|
|
12
10
|
from datetime import datetime
|
|
13
11
|
from roms_tools.setup.datasets import GLORYSDataset, CESMBGCDataset
|
|
12
|
+
from roms_tools.setup.vertical_coordinate import compute_depth
|
|
14
13
|
from roms_tools.setup.utils import (
|
|
15
14
|
get_variable_metadata,
|
|
16
15
|
group_dataset,
|
|
@@ -22,6 +21,11 @@ from roms_tools.setup.utils import (
|
|
|
22
21
|
one_dim_fill,
|
|
23
22
|
nan_check,
|
|
24
23
|
substitute_nans_by_fillvalue,
|
|
24
|
+
interpolate_from_rho_to_u,
|
|
25
|
+
interpolate_from_rho_to_v,
|
|
26
|
+
convert_to_roms_time,
|
|
27
|
+
_to_yaml,
|
|
28
|
+
_from_yaml,
|
|
25
29
|
)
|
|
26
30
|
from roms_tools.setup.plot import _section_plot, _line_plot
|
|
27
31
|
import matplotlib.pyplot as plt
|
|
@@ -59,12 +63,12 @@ class BoundaryForcing:
|
|
|
59
63
|
- "physics": for physical atmospheric forcing.
|
|
60
64
|
- "bgc": for biogeochemical forcing.
|
|
61
65
|
|
|
62
|
-
model_reference_date : datetime, optional
|
|
63
|
-
Reference date for the model. Default is January 1, 2000.
|
|
64
66
|
apply_2d_horizontal_fill: bool, optional
|
|
65
67
|
Indicates whether to perform a two-dimensional horizontal fill on the source data prior to regridding to boundaries.
|
|
66
68
|
If `False`, a one-dimensional horizontal fill is performed separately on each of the four regridded boundaries.
|
|
67
69
|
Defaults to `False`.
|
|
70
|
+
model_reference_date : datetime, optional
|
|
71
|
+
Reference date for the model. Default is January 1, 2000.
|
|
68
72
|
use_dask: bool, optional
|
|
69
73
|
Indicates whether to use dask for processing. If True, data is processed with dask; if False, data is processed eagerly. Defaults to False.
|
|
70
74
|
|
|
@@ -93,8 +97,8 @@ class BoundaryForcing:
|
|
|
93
97
|
)
|
|
94
98
|
source: Dict[str, Union[str, Path, List[Union[str, Path]]]]
|
|
95
99
|
type: str = "physics"
|
|
96
|
-
model_reference_date: datetime = datetime(2000, 1, 1)
|
|
97
100
|
apply_2d_horizontal_fill: bool = False
|
|
101
|
+
model_reference_date: datetime = datetime(2000, 1, 1)
|
|
98
102
|
use_dask: bool = False
|
|
99
103
|
|
|
100
104
|
ds: xr.Dataset = field(init=False, repr=False)
|
|
@@ -114,8 +118,8 @@ class BoundaryForcing:
|
|
|
114
118
|
data.extrapolate_deepest_to_bottom()
|
|
115
119
|
data.apply_lateral_fill()
|
|
116
120
|
|
|
117
|
-
|
|
118
|
-
|
|
121
|
+
self._set_variable_info(data)
|
|
122
|
+
self._set_boundary_info()
|
|
119
123
|
ds = xr.Dataset()
|
|
120
124
|
|
|
121
125
|
for direction in ["south", "east", "north", "west"]:
|
|
@@ -123,10 +127,10 @@ class BoundaryForcing:
|
|
|
123
127
|
|
|
124
128
|
bdry_target_coords = {
|
|
125
129
|
"lat": target_coords["lat"].isel(
|
|
126
|
-
**bdry_coords["vector"][direction]
|
|
130
|
+
**self.bdry_coords["vector"][direction]
|
|
127
131
|
),
|
|
128
132
|
"lon": target_coords["lon"].isel(
|
|
129
|
-
**bdry_coords["vector"][direction]
|
|
133
|
+
**self.bdry_coords["vector"][direction]
|
|
130
134
|
),
|
|
131
135
|
"straddle": target_coords["straddle"],
|
|
132
136
|
}
|
|
@@ -144,11 +148,17 @@ class BoundaryForcing:
|
|
|
144
148
|
|
|
145
149
|
# lateral regridding of vector fields
|
|
146
150
|
vector_var_names = [
|
|
147
|
-
name
|
|
151
|
+
name
|
|
152
|
+
for name, info in self.variable_info.items()
|
|
153
|
+
if info["is_vector"]
|
|
148
154
|
]
|
|
149
155
|
if len(vector_var_names) > 0:
|
|
150
|
-
lon = target_coords["lon"].isel(
|
|
151
|
-
|
|
156
|
+
lon = target_coords["lon"].isel(
|
|
157
|
+
**self.bdry_coords["vector"][direction]
|
|
158
|
+
)
|
|
159
|
+
lat = target_coords["lat"].isel(
|
|
160
|
+
**self.bdry_coords["vector"][direction]
|
|
161
|
+
)
|
|
152
162
|
lateral_regrid = LateralRegrid(
|
|
153
163
|
{"lat": lat, "lon": lon}, bdry_data.dim_names
|
|
154
164
|
)
|
|
@@ -161,12 +171,16 @@ class BoundaryForcing:
|
|
|
161
171
|
# lateral regridding of tracer fields
|
|
162
172
|
tracer_var_names = [
|
|
163
173
|
name
|
|
164
|
-
for name, info in variable_info.items()
|
|
174
|
+
for name, info in self.variable_info.items()
|
|
165
175
|
if not info["is_vector"]
|
|
166
176
|
]
|
|
167
177
|
if len(tracer_var_names) > 0:
|
|
168
|
-
lon = target_coords["lon"].isel(
|
|
169
|
-
|
|
178
|
+
lon = target_coords["lon"].isel(
|
|
179
|
+
**self.bdry_coords["rho"][direction]
|
|
180
|
+
)
|
|
181
|
+
lat = target_coords["lat"].isel(
|
|
182
|
+
**self.bdry_coords["rho"][direction]
|
|
183
|
+
)
|
|
170
184
|
lateral_regrid = LateralRegrid(
|
|
171
185
|
{"lat": lat, "lon": lon}, bdry_data.dim_names
|
|
172
186
|
)
|
|
@@ -177,9 +191,9 @@ class BoundaryForcing:
|
|
|
177
191
|
)
|
|
178
192
|
|
|
179
193
|
# rotation of velocities and interpolation to u/v points
|
|
180
|
-
if "u" in variable_info and "v" in variable_info:
|
|
194
|
+
if "u" in self.variable_info and "v" in self.variable_info:
|
|
181
195
|
angle = target_coords["angle"].isel(
|
|
182
|
-
**bdry_coords["vector"][direction]
|
|
196
|
+
**self.bdry_coords["vector"][direction]
|
|
183
197
|
)
|
|
184
198
|
(processed_fields["u"], processed_fields["v"],) = rotate_velocities(
|
|
185
199
|
processed_fields["u"],
|
|
@@ -189,54 +203,68 @@ class BoundaryForcing:
|
|
|
189
203
|
)
|
|
190
204
|
|
|
191
205
|
# selection of outermost margin for u/v variables
|
|
192
|
-
for var_name in variable_info.keys():
|
|
206
|
+
for var_name in self.variable_info.keys():
|
|
193
207
|
if var_name in processed_fields:
|
|
194
|
-
location = variable_info[var_name]["location"]
|
|
208
|
+
location = self.variable_info[var_name]["location"]
|
|
195
209
|
if location in ["u", "v"]:
|
|
196
210
|
processed_fields[var_name] = processed_fields[
|
|
197
211
|
var_name
|
|
198
|
-
].isel(**bdry_coords[location][direction])
|
|
212
|
+
].isel(**self.bdry_coords[location][direction])
|
|
199
213
|
|
|
200
214
|
if not self.apply_2d_horizontal_fill:
|
|
201
215
|
self._validate_1d_fill(
|
|
202
216
|
processed_fields,
|
|
203
|
-
variable_info,
|
|
204
|
-
bdry_coords,
|
|
205
217
|
direction,
|
|
206
218
|
bdry_data.dim_names["depth"],
|
|
207
219
|
)
|
|
208
220
|
processed_fields = apply_1d_horizontal_fill(processed_fields)
|
|
209
221
|
|
|
210
|
-
|
|
222
|
+
var_names_dict = {}
|
|
211
223
|
for location in ["rho", "u", "v"]:
|
|
212
|
-
|
|
224
|
+
var_names_dict[location] = [
|
|
213
225
|
name
|
|
214
|
-
for name, info in variable_info.items()
|
|
226
|
+
for name, info in self.variable_info.items()
|
|
215
227
|
if info["location"] == location and info["is_3d"]
|
|
216
228
|
]
|
|
217
|
-
|
|
229
|
+
# compute layer depth coordinates
|
|
230
|
+
if len(var_names_dict["u"]) > 0 or len(var_names_dict["v"]) > 0:
|
|
231
|
+
self._get_vertical_coordinates(
|
|
232
|
+
type="layer",
|
|
233
|
+
direction=direction,
|
|
234
|
+
additional_locations=["u", "v"],
|
|
235
|
+
)
|
|
236
|
+
else:
|
|
237
|
+
if len(var_names_dict["rho"]) > 0:
|
|
238
|
+
self._get_vertical_coordinates(
|
|
239
|
+
type="layer", direction=direction, additional_locations=[]
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# vertical regridding
|
|
243
|
+
for location in ["rho", "u", "v"]:
|
|
244
|
+
if len(var_names_dict[location]) > 0:
|
|
218
245
|
vertical_regrid = VerticalRegrid(
|
|
219
|
-
self.grid.ds[f"layer_depth_{location}"]
|
|
220
|
-
**bdry_coords[location][direction]
|
|
221
|
-
),
|
|
246
|
+
self.grid.ds[f"layer_depth_{location}_{direction}"],
|
|
222
247
|
bdry_data.ds[bdry_data.dim_names["depth"]],
|
|
223
248
|
)
|
|
224
|
-
for var_name in
|
|
249
|
+
for var_name in var_names_dict[location]:
|
|
225
250
|
if var_name in processed_fields:
|
|
226
251
|
processed_fields[var_name] = vertical_regrid.apply(
|
|
227
252
|
processed_fields[var_name]
|
|
228
253
|
)
|
|
229
254
|
|
|
230
255
|
# compute barotropic velocities
|
|
231
|
-
if "u" in variable_info and "v" in variable_info:
|
|
232
|
-
|
|
256
|
+
if "u" in self.variable_info and "v" in self.variable_info:
|
|
257
|
+
self._get_vertical_coordinates(
|
|
258
|
+
type="interface",
|
|
259
|
+
direction=direction,
|
|
260
|
+
additional_locations=["u", "v"],
|
|
261
|
+
)
|
|
262
|
+
for location in ["u", "v"]:
|
|
233
263
|
processed_fields[
|
|
234
|
-
f"{
|
|
264
|
+
f"{location}bar"
|
|
235
265
|
] = compute_barotropic_velocity(
|
|
236
|
-
processed_fields[
|
|
237
|
-
self.grid.ds[f"interface_depth_{
|
|
238
|
-
**bdry_coords[var_name][direction]
|
|
239
|
-
),
|
|
266
|
+
processed_fields[location],
|
|
267
|
+
self.grid.ds[f"interface_depth_{location}_{direction}"],
|
|
240
268
|
)
|
|
241
269
|
|
|
242
270
|
# Reorder dimensions
|
|
@@ -251,7 +279,7 @@ class BoundaryForcing:
|
|
|
251
279
|
# Add global information
|
|
252
280
|
ds = self._add_global_metadata(data, ds)
|
|
253
281
|
|
|
254
|
-
self._validate(ds
|
|
282
|
+
self._validate(ds)
|
|
255
283
|
|
|
256
284
|
# substitute NaNs over land by a fill value to avoid blow-up of ROMS
|
|
257
285
|
for var_name in ds.data_vars:
|
|
@@ -316,11 +344,15 @@ class BoundaryForcing:
|
|
|
316
344
|
- `vector_pair`: For vector variables, this indicates the associated variable that forms the vector (e.g., 'u' and 'v').
|
|
317
345
|
- `is_3d`: Indicates whether the variable is 3D (True for variables like 'temp' and 'salt') or 2D (False for 'zeta').
|
|
318
346
|
|
|
347
|
+
Parameters
|
|
348
|
+
----------
|
|
349
|
+
data : object
|
|
350
|
+
An object that contains variable names for the data being processed. This is used to set variable information for biogeochemical data.
|
|
351
|
+
|
|
319
352
|
Returns
|
|
320
353
|
-------
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
about each variable, including 'location', 'is_vector', 'vector_pair', and 'is_3d'.
|
|
354
|
+
None
|
|
355
|
+
This method updates the instance attribute `variable_info` with the metadata dictionary for the variables.
|
|
324
356
|
"""
|
|
325
357
|
default_info = {
|
|
326
358
|
"location": "rho",
|
|
@@ -378,7 +410,7 @@ class BoundaryForcing:
|
|
|
378
410
|
else:
|
|
379
411
|
variable_info[var_name] = {**default_info, "validate": False}
|
|
380
412
|
|
|
381
|
-
|
|
413
|
+
object.__setattr__(self, "variable_info", variable_info)
|
|
382
414
|
|
|
383
415
|
def _write_into_dataset(self, direction, processed_fields, ds=None):
|
|
384
416
|
if ds is None:
|
|
@@ -413,45 +445,178 @@ class BoundaryForcing:
|
|
|
413
445
|
"lat_v",
|
|
414
446
|
"lon_v",
|
|
415
447
|
]
|
|
416
|
-
|
|
448
|
+
suffixes = ["", "_south", "_east", "_north", "_west"]
|
|
449
|
+
# Existing variables with suffixes
|
|
450
|
+
existing_vars = []
|
|
451
|
+
for var_name in variables_to_drop:
|
|
452
|
+
for suffix in suffixes:
|
|
453
|
+
full_var_name = f"{var_name}{suffix}"
|
|
454
|
+
if full_var_name in ds:
|
|
455
|
+
existing_vars.append(full_var_name)
|
|
456
|
+
|
|
417
457
|
ds = ds.drop_vars(existing_vars)
|
|
418
458
|
|
|
419
459
|
return ds
|
|
420
460
|
|
|
421
|
-
def
|
|
461
|
+
def _set_boundary_info(self):
|
|
462
|
+
"""Updates boundary coordinates for rho, u, and v variables on the grid.
|
|
463
|
+
|
|
464
|
+
This method determines the boundary points for the grid variables by specifying the
|
|
465
|
+
indices for the south, east, north, and west boundaries. The resulting boundary
|
|
466
|
+
information is stored in the instance attribute `bdry_coords`.
|
|
467
|
+
|
|
468
|
+
Returns
|
|
469
|
+
-------
|
|
470
|
+
None
|
|
471
|
+
The method does not return a value. Instead, it updates the instance attribute
|
|
472
|
+
`bdry_coords`, which is a dictionary structured as follows:
|
|
473
|
+
- Keys: Variable types ("rho", "u", "v", "vector").
|
|
474
|
+
- Values: Nested dictionaries mapping each direction ("south", "east", "north", "west")
|
|
475
|
+
to their corresponding boundary coordinates. The coordinates are specified in terms of
|
|
476
|
+
grid indices for the respective variable types.
|
|
477
|
+
"""
|
|
478
|
+
|
|
479
|
+
bdry_coords = {
|
|
480
|
+
"rho": {
|
|
481
|
+
"south": {"eta_rho": 0},
|
|
482
|
+
"east": {"xi_rho": -1},
|
|
483
|
+
"north": {"eta_rho": -1},
|
|
484
|
+
"west": {"xi_rho": 0},
|
|
485
|
+
},
|
|
486
|
+
"u": {
|
|
487
|
+
"south": {"eta_rho": 0},
|
|
488
|
+
"east": {"xi_u": -1},
|
|
489
|
+
"north": {"eta_rho": -1},
|
|
490
|
+
"west": {"xi_u": 0},
|
|
491
|
+
},
|
|
492
|
+
"v": {
|
|
493
|
+
"south": {"eta_v": 0},
|
|
494
|
+
"east": {"xi_rho": -1},
|
|
495
|
+
"north": {"eta_v": -1},
|
|
496
|
+
"west": {"xi_rho": 0},
|
|
497
|
+
},
|
|
498
|
+
"vector": {
|
|
499
|
+
"south": {"eta_rho": [0, 1]},
|
|
500
|
+
"east": {"xi_rho": [-2, -1]},
|
|
501
|
+
"north": {"eta_rho": [-2, -1]},
|
|
502
|
+
"west": {"xi_rho": [0, 1]},
|
|
503
|
+
},
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
object.__setattr__(self, "bdry_coords", bdry_coords)
|
|
507
|
+
|
|
508
|
+
def _get_vertical_coordinates(
|
|
509
|
+
self, type, direction, additional_locations=["u", "v"]
|
|
510
|
+
):
|
|
422
511
|
"""Retrieve layer and interface depth coordinates for a specified grid boundary.
|
|
423
512
|
|
|
424
|
-
This method
|
|
425
|
-
|
|
426
|
-
|
|
513
|
+
This method computes and updates the layer and interface depth coordinates along a specified
|
|
514
|
+
boundary (north, south, east, or west). It handles depth calculations for rho points and
|
|
515
|
+
additional specified locations (u and v).
|
|
427
516
|
|
|
428
517
|
Parameters
|
|
429
518
|
----------
|
|
430
|
-
|
|
431
|
-
The
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
The type of grid point to retrieve coordinates for. Valid options are
|
|
435
|
-
"rho" for the grid's central points, "u" for the u-flux points, and "v"
|
|
436
|
-
for the v-flux points.
|
|
519
|
+
type : str
|
|
520
|
+
The type of depth coordinate to retrieve. Valid options are:
|
|
521
|
+
- "layer": Retrieves layer depth coordinates.
|
|
522
|
+
- "interface": Retrieves interface depth coordinates.
|
|
437
523
|
|
|
438
|
-
|
|
524
|
+
direction : str
|
|
525
|
+
The direction of the boundary to retrieve coordinates for. Valid options are:
|
|
526
|
+
- "north"
|
|
527
|
+
- "south"
|
|
528
|
+
- "east"
|
|
529
|
+
- "west"
|
|
530
|
+
|
|
531
|
+
additional_locations : list of str, optional
|
|
532
|
+
Specifies additional locations to compute depth coordinates for. Default is ["u", "v"].
|
|
533
|
+
Valid options include:
|
|
534
|
+
- "u": Computes depth coordinates for u points.
|
|
535
|
+
- "v": Computes depth coordinates for v points.
|
|
536
|
+
|
|
537
|
+
Updates
|
|
439
538
|
-------
|
|
440
|
-
|
|
441
|
-
The
|
|
442
|
-
|
|
539
|
+
self.grid.ds : xarray.Dataset
|
|
540
|
+
The dataset is updated with the following vertical depth coordinates:
|
|
541
|
+
- f"{type}_depth_rho_{direction}": Depth coordinates at rho points.
|
|
542
|
+
- f"{type}_depth_u_{direction}": Depth coordinates at u points (if applicable).
|
|
543
|
+
- f"{type}_depth_v_{direction}": Depth coordinates at v points (if applicable).
|
|
443
544
|
"""
|
|
444
545
|
|
|
445
|
-
|
|
546
|
+
layer_vars = []
|
|
547
|
+
for location in ["rho"] + additional_locations:
|
|
548
|
+
layer_vars.append(f"{type}_depth_{location}_{direction}")
|
|
446
549
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
550
|
+
if all(layer_var in self.grid.ds for layer_var in layer_vars):
|
|
551
|
+
# Vertical coordinate data already exists
|
|
552
|
+
pass
|
|
553
|
+
|
|
554
|
+
elif f"{type}_depth_rho" in self.grid.ds:
|
|
555
|
+
depth = self.grid.ds[f"{type}_depth_rho"]
|
|
556
|
+
depth.attrs["long_name"] = f"{type} depth at rho-points"
|
|
557
|
+
depth.attrs["units"] = "m"
|
|
558
|
+
self.grid.ds[f"{type}_depth_rho_{direction}"] = depth.isel(
|
|
559
|
+
**self.bdry_coords["rho"][direction]
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
if "u" in additional_locations or "v" in additional_locations:
|
|
563
|
+
# selection of margin consisting of 2 grid cells
|
|
564
|
+
depth = depth.isel(**self.bdry_coords["vector"][direction])
|
|
565
|
+
# interpolation
|
|
566
|
+
if "u" in additional_locations:
|
|
567
|
+
depth_u = interpolate_from_rho_to_u(depth)
|
|
568
|
+
depth_u.attrs["long_name"] = f"{type} depth at u-points"
|
|
569
|
+
depth_u.attrs["units"] = "m"
|
|
570
|
+
self.grid.ds[f"{type}_depth_u_{direction}"] = depth_u.isel(
|
|
571
|
+
**self.bdry_coords["u"][direction]
|
|
572
|
+
)
|
|
573
|
+
if "v" in additional_locations:
|
|
574
|
+
depth_v = interpolate_from_rho_to_v(depth)
|
|
575
|
+
depth_v.attrs["long_name"] = f"{type} depth at v-points"
|
|
576
|
+
depth_v.attrs["units"] = "m"
|
|
577
|
+
self.grid.ds[f"{type}_depth_v_{direction}"] = depth_v.isel(
|
|
578
|
+
**self.bdry_coords["v"][direction]
|
|
579
|
+
)
|
|
580
|
+
else:
|
|
581
|
+
if "u" in additional_locations or "v" in additional_locations:
|
|
582
|
+
h = self.grid.ds["h"].isel(**self.bdry_coords["vector"][direction])
|
|
583
|
+
else:
|
|
584
|
+
h = self.grid.ds["h"].isel(**self.bdry_coords["rho"][direction])
|
|
585
|
+
if type == "layer":
|
|
586
|
+
depth = compute_depth(
|
|
587
|
+
0, h, self.grid.hc, self.grid.ds.Cs_r, self.grid.ds.sigma_r
|
|
588
|
+
)
|
|
589
|
+
else:
|
|
590
|
+
depth = compute_depth(
|
|
591
|
+
0, h, self.grid.hc, self.grid.ds.Cs_w, self.grid.ds.sigma_w
|
|
592
|
+
)
|
|
453
593
|
|
|
454
|
-
|
|
594
|
+
if "u" in additional_locations or "v" in additional_locations:
|
|
595
|
+
depth.attrs["long_name"] = f"{type} depth at rho-points"
|
|
596
|
+
depth.attrs["units"] = "m"
|
|
597
|
+
self.grid.ds[f"{type}_depth_rho_{direction}"] = depth.isel(
|
|
598
|
+
**self.bdry_coords["rho"][direction]
|
|
599
|
+
)
|
|
600
|
+
# selection of margin consisting of 2 grid cells
|
|
601
|
+
depth = depth.isel(**self.bdry_coords["vector"][direction])
|
|
602
|
+
# interpolation
|
|
603
|
+
depth_u = interpolate_from_rho_to_u(depth)
|
|
604
|
+
depth_v = interpolate_from_rho_to_v(depth)
|
|
605
|
+
# selection of outermost margin
|
|
606
|
+
depth_u.attrs["long_name"] = f"{type} depth at u-points"
|
|
607
|
+
depth_u.attrs["units"] = "m"
|
|
608
|
+
self.grid.ds[f"{type}_depth_u_{direction}"] = depth_u.isel(
|
|
609
|
+
**self.bdry_coords["u"][direction]
|
|
610
|
+
)
|
|
611
|
+
depth_v.attrs["long_name"] = f"{type} depth at v-points"
|
|
612
|
+
depth_v.attrs["units"] = "m"
|
|
613
|
+
self.grid.ds[f"{type}_depth_v_{direction}"] = depth_v.isel(
|
|
614
|
+
**self.bdry_coords["v"][direction]
|
|
615
|
+
)
|
|
616
|
+
else:
|
|
617
|
+
depth.attrs["long_name"] = f"{type} depth at rho-points"
|
|
618
|
+
depth.attrs["units"] = "m"
|
|
619
|
+
self.grid.ds[f"{type}_depth_rho_{direction}"] = depth
|
|
455
620
|
|
|
456
621
|
def _add_global_metadata(self, data, ds=None):
|
|
457
622
|
|
|
@@ -474,57 +639,17 @@ class BoundaryForcing:
|
|
|
474
639
|
ds.attrs["hc"] = self.grid.ds.attrs["hc"]
|
|
475
640
|
|
|
476
641
|
# Convert the time coordinate to the format expected by ROMS
|
|
477
|
-
|
|
478
|
-
ds.
|
|
479
|
-
|
|
480
|
-
ds = ds.assign_coords(
|
|
481
|
-
{"abs_time": np.datetime64(self.model_reference_date) + ds["time"]}
|
|
482
|
-
)
|
|
483
|
-
# Convert to pandas TimedeltaIndex
|
|
484
|
-
timedelta_index = pd.to_timedelta(ds["time"].values)
|
|
485
|
-
|
|
486
|
-
# Determine the start of the year for the base_datetime
|
|
487
|
-
start_of_year = datetime(self.model_reference_date.year, 1, 1)
|
|
488
|
-
|
|
489
|
-
# Calculate the offset from midnight of the new year
|
|
490
|
-
offset = self.model_reference_date - start_of_year
|
|
491
|
-
|
|
492
|
-
# Convert the timedelta to nanoseconds first, then to days
|
|
493
|
-
bry_time = xr.DataArray(
|
|
494
|
-
(timedelta_index - offset).view("int64") / 3600 / 24 * 1e-9,
|
|
495
|
-
dims="time",
|
|
496
|
-
)
|
|
497
|
-
|
|
498
|
-
else:
|
|
499
|
-
# Preserve absolute time coordinate for readability
|
|
500
|
-
ds = ds.assign_coords({"abs_time": ds["time"]})
|
|
501
|
-
bry_time = (
|
|
502
|
-
(ds["time"] - np.datetime64(self.model_reference_date)).astype(
|
|
503
|
-
"float64"
|
|
504
|
-
)
|
|
505
|
-
/ 3600
|
|
506
|
-
/ 24
|
|
507
|
-
* 1e-9
|
|
508
|
-
)
|
|
642
|
+
ds, bry_time = convert_to_roms_time(
|
|
643
|
+
ds, self.model_reference_date, data.climatology
|
|
644
|
+
)
|
|
509
645
|
|
|
510
646
|
ds = ds.assign_coords({"bry_time": bry_time})
|
|
511
|
-
ds["bry_time"].attrs[
|
|
512
|
-
"long_name"
|
|
513
|
-
] = f"days since {str(self.model_reference_date)}"
|
|
514
|
-
ds["bry_time"].encoding["units"] = "days"
|
|
515
|
-
ds["bry_time"].attrs["units"] = "days"
|
|
516
647
|
ds = ds.swap_dims({"time": "bry_time"})
|
|
517
648
|
ds = ds.drop_vars("time")
|
|
518
|
-
ds.encoding["unlimited_dims"] = "bry_time"
|
|
519
|
-
|
|
520
|
-
if data.climatology:
|
|
521
|
-
ds["bry_time"].attrs["cycle_length"] = 365.25
|
|
522
649
|
|
|
523
650
|
return ds
|
|
524
651
|
|
|
525
|
-
def _validate_1d_fill(
|
|
526
|
-
self, processed_fields, variable_info, bdry_coords, direction, depth_dim
|
|
527
|
-
):
|
|
652
|
+
def _validate_1d_fill(self, processed_fields, direction, depth_dim):
|
|
528
653
|
"""Check if any boundary is divided by land and issue a warning if so,
|
|
529
654
|
suggesting the use of 2D horizontal fill for safer regridding.
|
|
530
655
|
|
|
@@ -534,15 +659,6 @@ class BoundaryForcing:
|
|
|
534
659
|
A dictionary where keys are variable names and values are `xarray.DataArray`
|
|
535
660
|
objects representing the processed data for each variable.
|
|
536
661
|
|
|
537
|
-
variable_info : dict
|
|
538
|
-
A dictionary containing metadata about each variable (e.g., location,
|
|
539
|
-
whether it's a 3D variable, etc.). Used to retrieve information for
|
|
540
|
-
validating each variable.
|
|
541
|
-
|
|
542
|
-
bdry_coords : dict
|
|
543
|
-
A dictionary containing boundary coordinates for different directions (north, south,
|
|
544
|
-
east, west), used to slice the boundary-specific data for each variable.
|
|
545
|
-
|
|
546
662
|
direction : str
|
|
547
663
|
The boundary direction being processed (e.g., "north", "south", "east", or "west").
|
|
548
664
|
|
|
@@ -558,8 +674,8 @@ class BoundaryForcing:
|
|
|
558
674
|
|
|
559
675
|
for var_name in processed_fields.keys():
|
|
560
676
|
# Only validate variables based on "validate" flag if use_dask is False
|
|
561
|
-
if not self.use_dask or variable_info[var_name]["validate"]:
|
|
562
|
-
location = variable_info[var_name]["location"]
|
|
677
|
+
if not self.use_dask or self.variable_info[var_name]["validate"]:
|
|
678
|
+
location = self.variable_info[var_name]["location"]
|
|
563
679
|
|
|
564
680
|
# Select the appropriate mask based on variable location
|
|
565
681
|
if location == "rho":
|
|
@@ -569,9 +685,9 @@ class BoundaryForcing:
|
|
|
569
685
|
elif location == "v":
|
|
570
686
|
mask = self.grid.ds.mask_v
|
|
571
687
|
|
|
572
|
-
mask = mask.isel(**bdry_coords[location][direction])
|
|
688
|
+
mask = mask.isel(**self.bdry_coords[location][direction])
|
|
573
689
|
|
|
574
|
-
if variable_info[var_name]["is_3d"]:
|
|
690
|
+
if self.variable_info[var_name]["is_3d"]:
|
|
575
691
|
da = processed_fields[var_name].isel({depth_dim: 0, "time": 0})
|
|
576
692
|
else:
|
|
577
693
|
da = processed_fields[var_name].isel({"time": 0})
|
|
@@ -590,7 +706,7 @@ class BoundaryForcing:
|
|
|
590
706
|
f"For {var_name}, the {direction}ern boundary is divided by land. It would be safer (but slower) to use `apply_2d_horizontal_fill = True`."
|
|
591
707
|
)
|
|
592
708
|
|
|
593
|
-
def _validate(self, ds
|
|
709
|
+
def _validate(self, ds):
|
|
594
710
|
"""Validate the dataset for NaN values at the first time step (bry_time=0) for
|
|
595
711
|
specified variables. If NaN values are found at wet points, this function raises
|
|
596
712
|
an error.
|
|
@@ -600,12 +716,6 @@ class BoundaryForcing:
|
|
|
600
716
|
ds : xarray.Dataset
|
|
601
717
|
The dataset to validate.
|
|
602
718
|
|
|
603
|
-
variable_info : dict
|
|
604
|
-
A dictionary containing metadata about the variables, including their locations (e.g., 'rho', 'u', 'v').
|
|
605
|
-
|
|
606
|
-
bdry_coords : dict
|
|
607
|
-
A dictionary containing the boundary coordinates for each variable location.
|
|
608
|
-
|
|
609
719
|
Raises
|
|
610
720
|
------
|
|
611
721
|
ValueError
|
|
@@ -617,10 +727,10 @@ class BoundaryForcing:
|
|
|
617
727
|
Validation is performed on the initial boundary time step (`bry_time=0`) for each
|
|
618
728
|
variable in the dataset.
|
|
619
729
|
"""
|
|
620
|
-
for var_name in variable_info:
|
|
730
|
+
for var_name in self.variable_info:
|
|
621
731
|
# only validate variables based on "validate" flag if use_dask is false
|
|
622
|
-
if not self.use_dask or variable_info[var_name]["validate"]:
|
|
623
|
-
location = variable_info[var_name]["location"]
|
|
732
|
+
if not self.use_dask or self.variable_info[var_name]["validate"]:
|
|
733
|
+
location = self.variable_info[var_name]["location"]
|
|
624
734
|
|
|
625
735
|
# Select the appropriate mask based on variable location
|
|
626
736
|
if location == "rho":
|
|
@@ -647,7 +757,7 @@ class BoundaryForcing:
|
|
|
647
757
|
|
|
648
758
|
nan_check(
|
|
649
759
|
ds[bdry_var_name].isel(bry_time=0),
|
|
650
|
-
mask.isel(**bdry_coords[location][direction]),
|
|
760
|
+
mask.isel(**self.bdry_coords[location][direction]),
|
|
651
761
|
error_message=error_message,
|
|
652
762
|
)
|
|
653
763
|
|
|
@@ -733,20 +843,13 @@ class BoundaryForcing:
|
|
|
733
843
|
field = field.load()
|
|
734
844
|
|
|
735
845
|
title = field.long_name
|
|
846
|
+
var_name_wo_direction, direction = var_name.split("_")
|
|
847
|
+
location = self.variable_info[var_name_wo_direction]["location"]
|
|
736
848
|
|
|
737
849
|
if "s_rho" in field.dims:
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
point = "v"
|
|
742
|
-
else:
|
|
743
|
-
point = "rho"
|
|
744
|
-
direction = var_name.split("_")[-1]
|
|
745
|
-
|
|
746
|
-
layer_depth, interface_depth = self._get_coordinates(direction, point)
|
|
747
|
-
|
|
748
|
-
field = field.assign_coords({"layer_depth": layer_depth})
|
|
749
|
-
|
|
850
|
+
field = field.assign_coords(
|
|
851
|
+
{"layer_depth": self.grid.ds[f"layer_depth_{location}_{direction}"]}
|
|
852
|
+
)
|
|
750
853
|
# chose colorbar
|
|
751
854
|
if var_name.startswith(("u", "v", "ubar", "vbar", "zeta")):
|
|
752
855
|
vmax = max(field.max().values, -field.min().values)
|
|
@@ -764,6 +867,19 @@ class BoundaryForcing:
|
|
|
764
867
|
|
|
765
868
|
if len(field.dims) == 2:
|
|
766
869
|
if layer_contours:
|
|
870
|
+
if location in ["u", "v"]:
|
|
871
|
+
additional_locations = ["u", "v"]
|
|
872
|
+
else:
|
|
873
|
+
additional_locations = []
|
|
874
|
+
self._get_vertical_coordinates(
|
|
875
|
+
type="interface",
|
|
876
|
+
direction=direction,
|
|
877
|
+
additional_locations=additional_locations,
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
interface_depth = self.grid.ds[
|
|
881
|
+
f"interface_depth_{location}_{direction}"
|
|
882
|
+
]
|
|
767
883
|
# restrict number of layer_contours to 10 for the sake of plot clearity
|
|
768
884
|
nr_layers = len(interface_depth["s_w"])
|
|
769
885
|
selected_layers = np.linspace(
|
|
@@ -859,46 +975,8 @@ class BoundaryForcing:
|
|
|
859
975
|
filepath : Union[str, Path]
|
|
860
976
|
The path to the YAML file where the parameters will be saved.
|
|
861
977
|
"""
|
|
862
|
-
filepath = Path(filepath)
|
|
863
978
|
|
|
864
|
-
|
|
865
|
-
grid_data = asdict(self.grid)
|
|
866
|
-
grid_data.pop("ds", None) # Exclude non-serializable fields
|
|
867
|
-
grid_data.pop("straddle", None)
|
|
868
|
-
|
|
869
|
-
# Include the version of roms-tools
|
|
870
|
-
try:
|
|
871
|
-
roms_tools_version = importlib.metadata.version("roms-tools")
|
|
872
|
-
except importlib.metadata.PackageNotFoundError:
|
|
873
|
-
roms_tools_version = "unknown"
|
|
874
|
-
|
|
875
|
-
# Create header
|
|
876
|
-
header = f"---\nroms_tools_version: {roms_tools_version}\n---\n"
|
|
877
|
-
|
|
878
|
-
grid_yaml_data = {"Grid": grid_data}
|
|
879
|
-
|
|
880
|
-
boundary_forcing_data = {
|
|
881
|
-
"BoundaryForcing": {
|
|
882
|
-
"start_time": self.start_time.isoformat(),
|
|
883
|
-
"end_time": self.end_time.isoformat(),
|
|
884
|
-
"boundaries": self.boundaries,
|
|
885
|
-
"source": self.source,
|
|
886
|
-
"type": self.type,
|
|
887
|
-
"apply_2d_horizontal_fill": self.apply_2d_horizontal_fill,
|
|
888
|
-
"model_reference_date": self.model_reference_date.isoformat(),
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
yaml_data = {
|
|
893
|
-
**grid_yaml_data,
|
|
894
|
-
**boundary_forcing_data,
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
with filepath.open("w") as file:
|
|
898
|
-
# Write header
|
|
899
|
-
file.write(header)
|
|
900
|
-
# Write YAML data
|
|
901
|
-
yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
|
|
979
|
+
_to_yaml(self, filepath)
|
|
902
980
|
|
|
903
981
|
@classmethod
|
|
904
982
|
def from_yaml(
|
|
@@ -919,80 +997,12 @@ class BoundaryForcing:
|
|
|
919
997
|
An instance of the BoundaryForcing class.
|
|
920
998
|
"""
|
|
921
999
|
filepath = Path(filepath)
|
|
922
|
-
# Read the entire file content
|
|
923
|
-
with filepath.open("r") as file:
|
|
924
|
-
file_content = file.read()
|
|
925
|
-
|
|
926
|
-
# Split the content into YAML documents
|
|
927
|
-
documents = list(yaml.safe_load_all(file_content))
|
|
928
|
-
|
|
929
|
-
boundary_forcing_data = None
|
|
930
|
-
|
|
931
|
-
# Process the YAML documents
|
|
932
|
-
for doc in documents:
|
|
933
|
-
if doc is None:
|
|
934
|
-
continue
|
|
935
|
-
if "BoundaryForcing" in doc:
|
|
936
|
-
boundary_forcing_data = doc["BoundaryForcing"]
|
|
937
|
-
break
|
|
938
|
-
|
|
939
|
-
if boundary_forcing_data is None:
|
|
940
|
-
raise ValueError("No BoundaryForcing configuration found in the YAML file.")
|
|
941
|
-
|
|
942
|
-
# Convert from string to datetime
|
|
943
|
-
for date_string in ["model_reference_date", "start_time", "end_time"]:
|
|
944
|
-
boundary_forcing_data[date_string] = datetime.fromisoformat(
|
|
945
|
-
boundary_forcing_data[date_string]
|
|
946
|
-
)
|
|
947
1000
|
|
|
948
1001
|
grid = Grid.from_yaml(filepath)
|
|
1002
|
+
params = _from_yaml(cls, filepath)
|
|
949
1003
|
|
|
950
1004
|
# Create and return an instance of InitialConditions
|
|
951
|
-
return cls(grid=grid, **
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
def get_boundary_info():
|
|
955
|
-
"""This function provides information about the boundary points for the rho, u, and
|
|
956
|
-
v variables on the grid, specifying the indices for the south, east, north, and west
|
|
957
|
-
boundaries.
|
|
958
|
-
|
|
959
|
-
Returns
|
|
960
|
-
-------
|
|
961
|
-
dict
|
|
962
|
-
A dictionary where keys are variable types ("rho", "u", "v"), and values
|
|
963
|
-
are nested dictionaries mapping directions ("south", "east", "north", "west")
|
|
964
|
-
to the corresponding boundary coordinates.
|
|
965
|
-
"""
|
|
966
|
-
|
|
967
|
-
# Boundary coordinates
|
|
968
|
-
bdry_coords = {
|
|
969
|
-
"rho": {
|
|
970
|
-
"south": {"eta_rho": 0},
|
|
971
|
-
"east": {"xi_rho": -1},
|
|
972
|
-
"north": {"eta_rho": -1},
|
|
973
|
-
"west": {"xi_rho": 0},
|
|
974
|
-
},
|
|
975
|
-
"u": {
|
|
976
|
-
"south": {"eta_rho": 0},
|
|
977
|
-
"east": {"xi_u": -1},
|
|
978
|
-
"north": {"eta_rho": -1},
|
|
979
|
-
"west": {"xi_u": 0},
|
|
980
|
-
},
|
|
981
|
-
"v": {
|
|
982
|
-
"south": {"eta_v": 0},
|
|
983
|
-
"east": {"xi_rho": -1},
|
|
984
|
-
"north": {"eta_v": -1},
|
|
985
|
-
"west": {"xi_rho": 0},
|
|
986
|
-
},
|
|
987
|
-
"vector": {
|
|
988
|
-
"south": {"eta_rho": [0, 1]},
|
|
989
|
-
"east": {"xi_rho": [-2, -1]},
|
|
990
|
-
"north": {"eta_rho": [-2, -1]},
|
|
991
|
-
"west": {"xi_rho": [0, 1]},
|
|
992
|
-
},
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
return bdry_coords
|
|
1005
|
+
return cls(grid=grid, **params, use_dask=use_dask)
|
|
996
1006
|
|
|
997
1007
|
|
|
998
1008
|
def apply_1d_horizontal_fill(processed_fields: dict) -> dict:
|