roms-tools 1.4.2__py3-none-any.whl → 1.5.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.
- roms_tools/_version.py +1 -1
- roms_tools/setup/boundary_forcing.py +276 -99
- roms_tools/setup/datasets.py +19 -15
- roms_tools/setup/fill.py +38 -2
- roms_tools/setup/initial_conditions.py +170 -44
- roms_tools/setup/regrid.py +198 -0
- roms_tools/setup/surface_forcing.py +136 -51
- roms_tools/setup/tides.py +103 -31
- roms_tools/setup/utils.py +235 -40
- 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 +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air_alt/0.0.0 +0 -0
- 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 +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air_alt/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/temp_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/u_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/ubar_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_east/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_north/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_south/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/v_west/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/vbar_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ALK_ALT_CO2/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DIC_ALT_CO2/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOCr/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DON/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DONr/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOP/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/DOPr/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Fe/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Lig/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NH4/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/NO3/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/O2/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/PO4/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/SiO3/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatChl/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatFe/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatP/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diatSi/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazChl/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazFe/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/diazP/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/salt/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spCaCO3/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spChl/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spFe/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/spP/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/temp/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/u/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/ubar/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/v/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/vbar/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zeta/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/zooC/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_fill.py +43 -14
- roms_tools/tests/test_setup/test_regrid.py +59 -0
- roms_tools/tests/test_setup/test_surface_forcing.py +18 -0
- {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/METADATA +2 -2
- {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/RECORD +222 -221
- roms_tools/setup/mixins.py +0 -227
- {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/LICENSE +0 -0
- {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/WHEEL +0 -0
- {roms_tools-1.4.2.dist-info → roms_tools-1.5.0.dist-info}/top_level.txt +0 -0
roms_tools/_version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# Do not change! Do not track in version control!
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.5.0"
|
|
@@ -6,16 +6,21 @@ import importlib.metadata
|
|
|
6
6
|
from typing import Dict, Union, List
|
|
7
7
|
from dataclasses import dataclass, field, asdict
|
|
8
8
|
from roms_tools.setup.grid import Grid
|
|
9
|
-
from roms_tools.setup.
|
|
9
|
+
from roms_tools.setup.fill import _lateral_fill
|
|
10
|
+
from roms_tools.setup.regrid import _lateral_regrid, _vertical_regrid
|
|
10
11
|
from datetime import datetime
|
|
11
12
|
from roms_tools.setup.datasets import GLORYSDataset, CESMBGCDataset
|
|
12
13
|
from roms_tools.setup.utils import (
|
|
13
14
|
nan_check,
|
|
14
15
|
substitute_nans_by_fillvalue,
|
|
15
16
|
get_variable_metadata,
|
|
16
|
-
get_boundary_info,
|
|
17
17
|
group_dataset,
|
|
18
18
|
save_datasets,
|
|
19
|
+
get_target_coords,
|
|
20
|
+
rotate_velocities,
|
|
21
|
+
compute_barotropic_velocity,
|
|
22
|
+
_extrapolate_deepest_to_bottom,
|
|
23
|
+
transpose_dimensions,
|
|
19
24
|
)
|
|
20
25
|
from roms_tools.setup.plot import _section_plot, _line_plot
|
|
21
26
|
import matplotlib.pyplot as plt
|
|
@@ -23,7 +28,7 @@ from pathlib import Path
|
|
|
23
28
|
|
|
24
29
|
|
|
25
30
|
@dataclass(frozen=True, kw_only=True)
|
|
26
|
-
class BoundaryForcing
|
|
31
|
+
class BoundaryForcing:
|
|
27
32
|
"""Represents boundary forcing input data for ROMS.
|
|
28
33
|
|
|
29
34
|
Parameters
|
|
@@ -91,33 +96,115 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
91
96
|
def __post_init__(self):
|
|
92
97
|
|
|
93
98
|
self._input_checks()
|
|
94
|
-
|
|
99
|
+
target_coords = get_target_coords(self.grid)
|
|
95
100
|
|
|
96
101
|
data = self._get_data()
|
|
97
102
|
data.choose_subdomain(
|
|
98
|
-
latitude_range=[
|
|
99
|
-
|
|
103
|
+
latitude_range=[
|
|
104
|
+
target_coords["lat"].min().values,
|
|
105
|
+
target_coords["lat"].max().values,
|
|
106
|
+
],
|
|
107
|
+
longitude_range=[
|
|
108
|
+
target_coords["lon"].min().values,
|
|
109
|
+
target_coords["lon"].max().values,
|
|
110
|
+
],
|
|
100
111
|
margin=2,
|
|
101
|
-
straddle=straddle,
|
|
112
|
+
straddle=target_coords["straddle"],
|
|
102
113
|
)
|
|
103
114
|
|
|
104
|
-
|
|
105
|
-
vars_2d = ["zeta"]
|
|
106
|
-
vars_3d = ["temp", "salt", "u", "v"]
|
|
107
|
-
elif self.type == "bgc":
|
|
108
|
-
vars_2d = []
|
|
109
|
-
vars_3d = data.var_names.keys()
|
|
115
|
+
variable_info = self._set_variable_info(data)
|
|
110
116
|
|
|
111
|
-
data_vars =
|
|
117
|
+
data_vars = {}
|
|
118
|
+
data_vars = _extrapolate_deepest_to_bottom(data_vars, data)
|
|
119
|
+
data_vars = _lateral_fill(data_vars, data)
|
|
112
120
|
|
|
113
|
-
if self.type == "physics":
|
|
114
|
-
data_vars = super()._process_velocities(data_vars, angle, "u", "v")
|
|
115
|
-
object.__setattr__(data, "data_vars", data_vars)
|
|
116
|
-
|
|
117
|
-
d_meta = get_variable_metadata()
|
|
118
121
|
bdry_coords = get_boundary_info()
|
|
122
|
+
ds = xr.Dataset()
|
|
123
|
+
for direction in ["south", "east", "north", "west"]:
|
|
124
|
+
if self.boundaries[direction]:
|
|
125
|
+
|
|
126
|
+
bdry_data_vars = data_vars.copy()
|
|
127
|
+
|
|
128
|
+
# lateral regridding of vector fields
|
|
129
|
+
vector_var_names = [
|
|
130
|
+
name for name, info in variable_info.items() if info["is_vector"]
|
|
131
|
+
]
|
|
132
|
+
if len(vector_var_names) > 0:
|
|
133
|
+
lon = target_coords["lon"].isel(**bdry_coords["vector"][direction])
|
|
134
|
+
lat = target_coords["lat"].isel(**bdry_coords["vector"][direction])
|
|
135
|
+
bdry_data_vars = _lateral_regrid(
|
|
136
|
+
data, lon, lat, bdry_data_vars, vector_var_names
|
|
137
|
+
)
|
|
138
|
+
# lateral regridding of tracer fields
|
|
139
|
+
tracer_var_names = [
|
|
140
|
+
name
|
|
141
|
+
for name, info in variable_info.items()
|
|
142
|
+
if not info["is_vector"]
|
|
143
|
+
]
|
|
144
|
+
if len(tracer_var_names) > 0:
|
|
145
|
+
lon = target_coords["lon"].isel(**bdry_coords["rho"][direction])
|
|
146
|
+
lat = target_coords["lat"].isel(**bdry_coords["rho"][direction])
|
|
147
|
+
bdry_data_vars = _lateral_regrid(
|
|
148
|
+
data, lon, lat, bdry_data_vars, tracer_var_names
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# rotation of velocities and interpolation to u/v points
|
|
152
|
+
if "u" in variable_info and "v" in variable_info:
|
|
153
|
+
angle = target_coords["angle"].isel(
|
|
154
|
+
**bdry_coords["vector"][direction]
|
|
155
|
+
)
|
|
156
|
+
(bdry_data_vars["u"], bdry_data_vars["v"],) = rotate_velocities(
|
|
157
|
+
bdry_data_vars["u"],
|
|
158
|
+
bdry_data_vars["v"],
|
|
159
|
+
angle,
|
|
160
|
+
interpolate=True,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# selection of outermost margin for u/v variables
|
|
164
|
+
for var in variable_info.keys():
|
|
165
|
+
if var in bdry_data_vars:
|
|
166
|
+
location = variable_info[var]["location"]
|
|
167
|
+
if location in ["u", "v"]:
|
|
168
|
+
bdry_data_vars[var] = bdry_data_vars[var].isel(
|
|
169
|
+
**bdry_coords[location][direction]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# vertical regridding
|
|
173
|
+
for location in ["rho", "u", "v"]:
|
|
174
|
+
var_names = [
|
|
175
|
+
name
|
|
176
|
+
for name, info in variable_info.items()
|
|
177
|
+
if info["location"] == location and info["is_3d"]
|
|
178
|
+
]
|
|
179
|
+
if len(var_names) > 0:
|
|
180
|
+
bdry_data_vars = _vertical_regrid(
|
|
181
|
+
data,
|
|
182
|
+
self.grid.ds[f"layer_depth_{location}"].isel(
|
|
183
|
+
**bdry_coords[location][direction],
|
|
184
|
+
),
|
|
185
|
+
bdry_data_vars,
|
|
186
|
+
var_names,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# compute barotropic velocities
|
|
190
|
+
if "u" in variable_info and "v" in variable_info:
|
|
191
|
+
for var in ["u", "v"]:
|
|
192
|
+
bdry_data_vars[f"{var}bar"] = compute_barotropic_velocity(
|
|
193
|
+
bdry_data_vars[var],
|
|
194
|
+
self.grid.ds[f"interface_depth_{var}"].isel(
|
|
195
|
+
**bdry_coords[var][direction]
|
|
196
|
+
),
|
|
197
|
+
)
|
|
119
198
|
|
|
120
|
-
|
|
199
|
+
# Reorder dimensions
|
|
200
|
+
for var in bdry_data_vars.keys():
|
|
201
|
+
bdry_data_vars[var] = transpose_dimensions(bdry_data_vars[var])
|
|
202
|
+
|
|
203
|
+
# Write the boundary data into dataset
|
|
204
|
+
ds = self._write_into_dataset(direction, bdry_data_vars, ds)
|
|
205
|
+
|
|
206
|
+
# Add global information
|
|
207
|
+
ds = self._add_global_metadata(data, ds)
|
|
121
208
|
|
|
122
209
|
# NaN values at wet points indicate that the raw data did not cover the domain, and the following will raise a ValueError
|
|
123
210
|
# this check works only for 2D fields because for 3D I extrapolate to bottom which eliminates NaNs
|
|
@@ -187,37 +274,86 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
187
274
|
|
|
188
275
|
return data
|
|
189
276
|
|
|
190
|
-
def
|
|
277
|
+
def _set_variable_info(self, data):
|
|
278
|
+
"""Sets up a dictionary with metadata for variables based on the type of data
|
|
279
|
+
(physics or BGC).
|
|
191
280
|
|
|
192
|
-
|
|
193
|
-
|
|
281
|
+
The dictionary contains the following information:
|
|
282
|
+
- `location`: Where the variable resides in the grid (e.g., rho, u, or v points).
|
|
283
|
+
- `is_vector`: Whether the variable is part of a vector (True for velocity components like 'u' and 'v').
|
|
284
|
+
- `vector_pair`: For vector variables, this indicates the associated variable that forms the vector (e.g., 'u' and 'v').
|
|
285
|
+
- `is_3d`: Indicates whether the variable is 3D (True for variables like 'temp' and 'salt') or 2D (False for 'zeta').
|
|
194
286
|
|
|
195
|
-
|
|
196
|
-
|
|
287
|
+
Returns
|
|
288
|
+
-------
|
|
289
|
+
dict
|
|
290
|
+
A dictionary where the keys are variable names and the values are dictionaries of metadata
|
|
291
|
+
about each variable, including 'location', 'is_vector', 'vector_pair', and 'is_3d'.
|
|
292
|
+
"""
|
|
293
|
+
default_info = {
|
|
294
|
+
"location": "rho",
|
|
295
|
+
"is_vector": False,
|
|
296
|
+
"vector_pair": None,
|
|
297
|
+
"is_3d": True,
|
|
298
|
+
}
|
|
197
299
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
300
|
+
# Define a dictionary for variable names and their associated information
|
|
301
|
+
if self.type == "physics":
|
|
302
|
+
variable_info = {
|
|
303
|
+
"zeta": {
|
|
304
|
+
"location": "rho",
|
|
305
|
+
"is_vector": False,
|
|
306
|
+
"vector_pair": None,
|
|
307
|
+
"is_3d": False,
|
|
308
|
+
},
|
|
309
|
+
"temp": default_info,
|
|
310
|
+
"salt": default_info,
|
|
311
|
+
"u": {
|
|
312
|
+
"location": "u",
|
|
313
|
+
"is_vector": True,
|
|
314
|
+
"vector_pair": "v",
|
|
315
|
+
"is_3d": True,
|
|
316
|
+
},
|
|
317
|
+
"v": {
|
|
318
|
+
"location": "v",
|
|
319
|
+
"is_vector": True,
|
|
320
|
+
"vector_pair": "u",
|
|
321
|
+
"is_3d": True,
|
|
322
|
+
},
|
|
323
|
+
"ubar": {
|
|
324
|
+
"location": "u",
|
|
325
|
+
"is_vector": True,
|
|
326
|
+
"vector_pair": "vbar",
|
|
327
|
+
"is_3d": False,
|
|
328
|
+
},
|
|
329
|
+
"vbar": {
|
|
330
|
+
"location": "v",
|
|
331
|
+
"is_vector": True,
|
|
332
|
+
"vector_pair": "ubar",
|
|
333
|
+
"is_3d": False,
|
|
334
|
+
},
|
|
335
|
+
}
|
|
336
|
+
elif self.type == "bgc":
|
|
337
|
+
variable_info = {}
|
|
338
|
+
for var in data.var_names.keys():
|
|
339
|
+
variable_info[var] = default_info
|
|
340
|
+
|
|
341
|
+
return variable_info
|
|
342
|
+
|
|
343
|
+
def _write_into_dataset(self, direction, data_vars, ds=None):
|
|
344
|
+
if ds is None:
|
|
345
|
+
ds = xr.Dataset()
|
|
346
|
+
|
|
347
|
+
d_meta = get_variable_metadata()
|
|
348
|
+
|
|
349
|
+
for var in data_vars.keys():
|
|
350
|
+
ds[f"{var}_{direction}"] = data_vars[var].astype(np.float32)
|
|
351
|
+
|
|
352
|
+
ds[f"{var}_{direction}"].attrs[
|
|
353
|
+
"long_name"
|
|
354
|
+
] = f"{direction}ern boundary {d_meta[var]['long_name']}"
|
|
355
|
+
|
|
356
|
+
ds[f"{var}_{direction}"].attrs["units"] = d_meta[var]["units"]
|
|
221
357
|
|
|
222
358
|
# Gracefully handle dropping variables that might not be present
|
|
223
359
|
variables_to_drop = [
|
|
@@ -238,56 +374,6 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
238
374
|
existing_vars = [var for var in variables_to_drop if var in ds]
|
|
239
375
|
ds = ds.drop_vars(existing_vars)
|
|
240
376
|
|
|
241
|
-
ds = self._add_global_metadata(ds)
|
|
242
|
-
|
|
243
|
-
# Convert the time coordinate to the format expected by ROMS
|
|
244
|
-
if data.climatology:
|
|
245
|
-
ds.attrs["climatology"] = str(True)
|
|
246
|
-
# Preserve absolute time coordinate for readability
|
|
247
|
-
ds = ds.assign_coords(
|
|
248
|
-
{"abs_time": np.datetime64(self.model_reference_date) + ds["time"]}
|
|
249
|
-
)
|
|
250
|
-
# Convert to pandas TimedeltaIndex
|
|
251
|
-
timedelta_index = pd.to_timedelta(ds["time"].values)
|
|
252
|
-
|
|
253
|
-
# Determine the start of the year for the base_datetime
|
|
254
|
-
start_of_year = datetime(self.model_reference_date.year, 1, 1)
|
|
255
|
-
|
|
256
|
-
# Calculate the offset from midnight of the new year
|
|
257
|
-
offset = self.model_reference_date - start_of_year
|
|
258
|
-
|
|
259
|
-
# Convert the timedelta to nanoseconds first, then to days
|
|
260
|
-
bry_time = xr.DataArray(
|
|
261
|
-
(timedelta_index - offset).view("int64") / 3600 / 24 * 1e-9,
|
|
262
|
-
dims="time",
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
else:
|
|
266
|
-
# Preserve absolute time coordinate for readability
|
|
267
|
-
ds = ds.assign_coords({"abs_time": ds["time"]})
|
|
268
|
-
# TODO: Check if we need to convert from 12:00:00 to 00:00:00 as in matlab scripts
|
|
269
|
-
bry_time = (
|
|
270
|
-
(ds["time"] - np.datetime64(self.model_reference_date)).astype(
|
|
271
|
-
"float64"
|
|
272
|
-
)
|
|
273
|
-
/ 3600
|
|
274
|
-
/ 24
|
|
275
|
-
* 1e-9
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
ds = ds.assign_coords({"bry_time": bry_time})
|
|
279
|
-
ds["bry_time"].attrs[
|
|
280
|
-
"long_name"
|
|
281
|
-
] = f"days since {str(self.model_reference_date)}"
|
|
282
|
-
ds["bry_time"].encoding["units"] = "days"
|
|
283
|
-
ds["bry_time"].attrs["units"] = "days"
|
|
284
|
-
ds = ds.swap_dims({"time": "bry_time"})
|
|
285
|
-
ds = ds.drop_vars("time")
|
|
286
|
-
ds.encoding["unlimited_dims"] = "bry_time"
|
|
287
|
-
|
|
288
|
-
if data.climatology:
|
|
289
|
-
ds["bry_time"].attrs["cycle_length"] = 365.25
|
|
290
|
-
|
|
291
377
|
return ds
|
|
292
378
|
|
|
293
379
|
def _get_coordinates(self, direction, point):
|
|
@@ -325,7 +411,7 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
325
411
|
|
|
326
412
|
return layer_depth, interface_depth
|
|
327
413
|
|
|
328
|
-
def _add_global_metadata(self, ds=None):
|
|
414
|
+
def _add_global_metadata(self, data, ds=None):
|
|
329
415
|
|
|
330
416
|
if ds is None:
|
|
331
417
|
ds = xr.Dataset()
|
|
@@ -345,6 +431,53 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
345
431
|
ds.attrs["theta_b"] = self.grid.ds.attrs["theta_b"]
|
|
346
432
|
ds.attrs["hc"] = self.grid.ds.attrs["hc"]
|
|
347
433
|
|
|
434
|
+
# Convert the time coordinate to the format expected by ROMS
|
|
435
|
+
if data.climatology:
|
|
436
|
+
ds.attrs["climatology"] = str(True)
|
|
437
|
+
# Preserve absolute time coordinate for readability
|
|
438
|
+
ds = ds.assign_coords(
|
|
439
|
+
{"abs_time": np.datetime64(self.model_reference_date) + ds["time"]}
|
|
440
|
+
)
|
|
441
|
+
# Convert to pandas TimedeltaIndex
|
|
442
|
+
timedelta_index = pd.to_timedelta(ds["time"].values)
|
|
443
|
+
|
|
444
|
+
# Determine the start of the year for the base_datetime
|
|
445
|
+
start_of_year = datetime(self.model_reference_date.year, 1, 1)
|
|
446
|
+
|
|
447
|
+
# Calculate the offset from midnight of the new year
|
|
448
|
+
offset = self.model_reference_date - start_of_year
|
|
449
|
+
|
|
450
|
+
# Convert the timedelta to nanoseconds first, then to days
|
|
451
|
+
bry_time = xr.DataArray(
|
|
452
|
+
(timedelta_index - offset).view("int64") / 3600 / 24 * 1e-9,
|
|
453
|
+
dims="time",
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
else:
|
|
457
|
+
# Preserve absolute time coordinate for readability
|
|
458
|
+
ds = ds.assign_coords({"abs_time": ds["time"]})
|
|
459
|
+
bry_time = (
|
|
460
|
+
(ds["time"] - np.datetime64(self.model_reference_date)).astype(
|
|
461
|
+
"float64"
|
|
462
|
+
)
|
|
463
|
+
/ 3600
|
|
464
|
+
/ 24
|
|
465
|
+
* 1e-9
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
ds = ds.assign_coords({"bry_time": bry_time})
|
|
469
|
+
ds["bry_time"].attrs[
|
|
470
|
+
"long_name"
|
|
471
|
+
] = f"days since {str(self.model_reference_date)}"
|
|
472
|
+
ds["bry_time"].encoding["units"] = "days"
|
|
473
|
+
ds["bry_time"].attrs["units"] = "days"
|
|
474
|
+
ds = ds.swap_dims({"time": "bry_time"})
|
|
475
|
+
ds = ds.drop_vars("time")
|
|
476
|
+
ds.encoding["unlimited_dims"] = "bry_time"
|
|
477
|
+
|
|
478
|
+
if data.climatology:
|
|
479
|
+
ds["bry_time"].attrs["cycle_length"] = 365.25
|
|
480
|
+
|
|
348
481
|
return ds
|
|
349
482
|
|
|
350
483
|
def plot(
|
|
@@ -621,3 +754,47 @@ class BoundaryForcing(ROMSToolsMixins):
|
|
|
621
754
|
|
|
622
755
|
# Create and return an instance of InitialConditions
|
|
623
756
|
return cls(grid=grid, **boundary_forcing_data, use_dask=use_dask)
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def get_boundary_info():
|
|
760
|
+
"""This function provides information about the boundary points for the rho, u, and
|
|
761
|
+
v variables on the grid, specifying the indices for the south, east, north, and west
|
|
762
|
+
boundaries.
|
|
763
|
+
|
|
764
|
+
Returns
|
|
765
|
+
-------
|
|
766
|
+
dict
|
|
767
|
+
A dictionary where keys are variable types ("rho", "u", "v"), and values
|
|
768
|
+
are nested dictionaries mapping directions ("south", "east", "north", "west")
|
|
769
|
+
to the corresponding boundary coordinates.
|
|
770
|
+
"""
|
|
771
|
+
|
|
772
|
+
# Boundary coordinates
|
|
773
|
+
bdry_coords = {
|
|
774
|
+
"rho": {
|
|
775
|
+
"south": {"eta_rho": 0},
|
|
776
|
+
"east": {"xi_rho": -1},
|
|
777
|
+
"north": {"eta_rho": -1},
|
|
778
|
+
"west": {"xi_rho": 0},
|
|
779
|
+
},
|
|
780
|
+
"u": {
|
|
781
|
+
"south": {"eta_rho": 0},
|
|
782
|
+
"east": {"xi_u": -1},
|
|
783
|
+
"north": {"eta_rho": -1},
|
|
784
|
+
"west": {"xi_u": 0},
|
|
785
|
+
},
|
|
786
|
+
"v": {
|
|
787
|
+
"south": {"eta_v": 0},
|
|
788
|
+
"east": {"xi_rho": -1},
|
|
789
|
+
"north": {"eta_v": -1},
|
|
790
|
+
"west": {"xi_rho": 0},
|
|
791
|
+
},
|
|
792
|
+
"vector": {
|
|
793
|
+
"south": {"eta_rho": [0, 1]},
|
|
794
|
+
"east": {"xi_rho": [-2, -1]},
|
|
795
|
+
"north": {"eta_rho": [-2, -1]},
|
|
796
|
+
"west": {"xi_rho": [0, 1]},
|
|
797
|
+
},
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
return bdry_coords
|
roms_tools/setup/datasets.py
CHANGED
|
@@ -805,11 +805,13 @@ class TPXODataset(Dataset):
|
|
|
805
805
|
if "depth" in self.var_names.keys():
|
|
806
806
|
mask = xr.where(self.ds["depth"] > 0, 1, 0)
|
|
807
807
|
|
|
808
|
-
for var in self.ds.data_vars:
|
|
809
|
-
self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
|
|
810
|
-
|
|
811
808
|
self.ds["mask"] = mask
|
|
812
809
|
|
|
810
|
+
# Remove "depth" from var_names
|
|
811
|
+
updated_var_names = {**self.var_names} # Create a copy of the dictionary
|
|
812
|
+
updated_var_names.pop("depth", None) # Remove "depth" if it exists
|
|
813
|
+
object.__setattr__(self, "var_names", updated_var_names)
|
|
814
|
+
|
|
813
815
|
|
|
814
816
|
@dataclass(frozen=True, kw_only=True)
|
|
815
817
|
class GLORYSDataset(Dataset):
|
|
@@ -878,11 +880,16 @@ class GLORYSDataset(Dataset):
|
|
|
878
880
|
0,
|
|
879
881
|
1,
|
|
880
882
|
)
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
self.
|
|
883
|
+
mask_vel = xr.where(
|
|
884
|
+
self.ds[self.var_names["u"]]
|
|
885
|
+
.isel({self.dim_names["time"]: 0, self.dim_names["depth"]: 0})
|
|
886
|
+
.isnull(),
|
|
887
|
+
0,
|
|
888
|
+
1,
|
|
889
|
+
)
|
|
884
890
|
|
|
885
891
|
self.ds["mask"] = mask
|
|
892
|
+
self.ds["mask_vel"] = mask_vel
|
|
886
893
|
|
|
887
894
|
|
|
888
895
|
@dataclass(frozen=True, kw_only=True)
|
|
@@ -1088,9 +1095,6 @@ class CESMBGCDataset(CESMDataset):
|
|
|
1088
1095
|
1,
|
|
1089
1096
|
)
|
|
1090
1097
|
|
|
1091
|
-
for var in self.ds.data_vars:
|
|
1092
|
-
self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
|
|
1093
|
-
|
|
1094
1098
|
self.ds["mask"] = mask
|
|
1095
1099
|
|
|
1096
1100
|
|
|
@@ -1160,9 +1164,6 @@ class CESMBGCSurfaceForcingDataset(CESMDataset):
|
|
|
1160
1164
|
1,
|
|
1161
1165
|
)
|
|
1162
1166
|
|
|
1163
|
-
for var in self.ds.data_vars:
|
|
1164
|
-
self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
|
|
1165
|
-
|
|
1166
1167
|
self.ds["mask"] = mask
|
|
1167
1168
|
|
|
1168
1169
|
|
|
@@ -1266,16 +1267,19 @@ class ERA5Dataset(Dataset):
|
|
|
1266
1267
|
|
|
1267
1268
|
# Update var_names dictionary
|
|
1268
1269
|
var_names = {**self.var_names, "qair": "qair"}
|
|
1270
|
+
var_names.pop("d2m")
|
|
1269
1271
|
object.__setattr__(self, "var_names", var_names)
|
|
1270
1272
|
|
|
1271
1273
|
if "mask" in self.var_names.keys():
|
|
1272
1274
|
mask = xr.where(self.ds[self.var_names["mask"]].isel(time=0).isnull(), 0, 1)
|
|
1273
1275
|
|
|
1274
|
-
for var in self.ds.data_vars:
|
|
1275
|
-
self.ds[var] = xr.where(mask == 1, self.ds[var], np.nan)
|
|
1276
|
-
|
|
1277
1276
|
self.ds["mask"] = mask
|
|
1278
1277
|
|
|
1278
|
+
# Remove mask from var_names dictionary
|
|
1279
|
+
var_names = self.var_names
|
|
1280
|
+
var_names.pop("mask")
|
|
1281
|
+
object.__setattr__(self, "var_names", var_names)
|
|
1282
|
+
|
|
1279
1283
|
|
|
1280
1284
|
@dataclass(frozen=True, kw_only=True)
|
|
1281
1285
|
class ERA5Correction(Dataset):
|
roms_tools/setup/fill.py
CHANGED
|
@@ -15,7 +15,7 @@ class LateralFill:
|
|
|
15
15
|
A 2D boolean mask indicating valid points (True) and land points (False).
|
|
16
16
|
Boundary points are automatically set to land (True).
|
|
17
17
|
dims : list of str
|
|
18
|
-
Dimensions along which to perform the lateral fill.
|
|
18
|
+
Dimensions along which to perform the lateral fill.
|
|
19
19
|
tol : float, optional
|
|
20
20
|
Tolerance for the iterative solver, determining convergence. Default is 1.0e-4.
|
|
21
21
|
|
|
@@ -65,7 +65,7 @@ class LateralFill:
|
|
|
65
65
|
non-NaN values.
|
|
66
66
|
"""
|
|
67
67
|
# Apply fill to anomaly field
|
|
68
|
-
mean = var.mean(dim=self.dims, skipna=True)
|
|
68
|
+
mean = var.where(self.mask).mean(dim=self.dims, skipna=True)
|
|
69
69
|
var = var - mean
|
|
70
70
|
|
|
71
71
|
# Setup the right-hand side (RHS): ocean points take their original values, land points are set to 0
|
|
@@ -301,3 +301,39 @@ def stencil_grid_mod(S, grid, msk, dtype=None, format=None):
|
|
|
301
301
|
data[4, i + diags[4]] = 0
|
|
302
302
|
|
|
303
303
|
return sparse.dia_matrix((data, diags), shape=(N_v, N_v)).asformat(format)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def _lateral_fill(data_vars, data):
|
|
307
|
+
"""Wrapper function to apply lateral fill to variables using the dataset's mask and
|
|
308
|
+
grid dimensions.
|
|
309
|
+
|
|
310
|
+
Parameters
|
|
311
|
+
----------
|
|
312
|
+
data_vars : dict of str : xarray.DataArray
|
|
313
|
+
Dictionary of variables to be filled.
|
|
314
|
+
data : Dataset
|
|
315
|
+
Dataset containing the mask and grid dimensions.
|
|
316
|
+
|
|
317
|
+
Returns
|
|
318
|
+
-------
|
|
319
|
+
dict of str : xarray.DataArray
|
|
320
|
+
Dictionary of filled variables.
|
|
321
|
+
"""
|
|
322
|
+
lateral_fill = LateralFill(
|
|
323
|
+
data.ds["mask"],
|
|
324
|
+
[data.dim_names["latitude"], data.dim_names["longitude"]],
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
if "mask_vel" in data.ds.data_vars:
|
|
328
|
+
lateral_fill_vel = LateralFill(
|
|
329
|
+
data.ds["mask_vel"],
|
|
330
|
+
[data.dim_names["latitude"], data.dim_names["longitude"]],
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
for var in data.var_names:
|
|
334
|
+
if var in ["u", "v"]:
|
|
335
|
+
data_vars[var] = lateral_fill_vel.apply(data_vars[var])
|
|
336
|
+
else:
|
|
337
|
+
data_vars[var] = lateral_fill.apply(data_vars[var])
|
|
338
|
+
|
|
339
|
+
return data_vars
|