roms-tools 1.5.0__py3-none-any.whl → 1.6.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 +226 -85
- roms_tools/setup/datasets.py +169 -39
- roms_tools/setup/fill.py +0 -36
- roms_tools/setup/initial_conditions.py +90 -69
- roms_tools/setup/regrid.py +43 -98
- roms_tools/setup/surface_forcing.py +68 -67
- roms_tools/setup/tides.py +60 -45
- roms_tools/setup/utils.py +25 -53
- roms_tools/tests/test_setup/test_boundary_forcing.py +42 -32
- 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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/dust/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/iron/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nhy/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/nox/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/pco2_air/0.0.0 +0 -0
- 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/dust/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/iron/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nhy/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/nox/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/pco2_air/0.0.0 +0 -0
- 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/.zmetadata +7 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +3 -0
- 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_south/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_south/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/.zattrs +1 -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_north/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +1 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/Tair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/lwrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/qair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/rain/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/swrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/uwnd/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/coarse_surface_forcing.zarr/vwnd/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/Tair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/lwrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/qair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/rain/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/swrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/uwnd/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/corrected_surface_forcing.zarr/vwnd/0.0.0 +0 -0
- 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_data/surface_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/.zmetadata +1 -1
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/Tair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/lwrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/qair/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/rain/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/swrad/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/uwnd/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/surface_forcing.zarr/vwnd/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/.zmetadata +4 -2
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/omega/.zattrs +3 -1
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Im/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/pot_Re/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Im/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/ssh_Re/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Im/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/u_Re/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Im/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/tidal_forcing.zarr/v_Re/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_datasets.py +79 -21
- roms_tools/tests/test_setup/test_fill.py +18 -105
- roms_tools/tests/test_setup/test_initial_conditions.py +21 -21
- roms_tools/tests/test_setup/test_regrid.py +2 -8
- roms_tools/tests/test_setup/test_surface_forcing.py +3 -3
- roms_tools/tests/test_setup/test_tides.py +1 -1
- {roms_tools-1.5.0.dist-info → roms_tools-1.6.0.dist-info}/METADATA +12 -3
- {roms_tools-1.5.0.dist-info → roms_tools-1.6.0.dist-info}/RECORD +238 -238
- {roms_tools-1.5.0.dist-info → roms_tools-1.6.0.dist-info}/WHEEL +1 -1
- {roms_tools-1.5.0.dist-info → roms_tools-1.6.0.dist-info}/LICENSE +0 -0
- {roms_tools-1.5.0.dist-info → roms_tools-1.6.0.dist-info}/top_level.txt +0 -0
roms_tools/setup/regrid.py
CHANGED
|
@@ -2,45 +2,38 @@ import xarray as xr
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class LateralRegrid:
|
|
5
|
-
"""
|
|
5
|
+
"""Handles lateral regridding of data onto a new spatial grid."""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Parameters
|
|
11
|
-
----------
|
|
12
|
-
data : DataContainer
|
|
13
|
-
Container with variables to be interpolated, including a `mask` and dimension names.
|
|
14
|
-
lon : xarray.DataArray
|
|
15
|
-
Target longitude coordinates.
|
|
16
|
-
lat : xarray.DataArray
|
|
17
|
-
Target latitude coordinates.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
def __init__(self, data, lon, lat):
|
|
21
|
-
"""Initializes the lateral fill and target grid coordinates.
|
|
7
|
+
def __init__(self, target_coords, source_dim_names):
|
|
8
|
+
"""Initialize target grid coordinates and names for grid dimensions.
|
|
22
9
|
|
|
23
10
|
Parameters
|
|
24
11
|
----------
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
12
|
+
target_coords : dict
|
|
13
|
+
Dictionary containing 'lon' and 'lat' as xarray.DataArrays representing
|
|
14
|
+
the longitude and latitude values of the target grid.
|
|
15
|
+
source_dim_names : dict
|
|
16
|
+
Dictionary specifying names for the latitude and longitude dimensions,
|
|
17
|
+
typically using keys like "latitude" and "longitude" to align with the dataset conventions.
|
|
18
|
+
|
|
19
|
+
Attributes
|
|
20
|
+
----------
|
|
21
|
+
coords : dict
|
|
22
|
+
Maps the dimension names to the corresponding latitude and longitude
|
|
23
|
+
DataArrays, providing easy access to target grid coordinates.
|
|
31
24
|
"""
|
|
32
25
|
|
|
33
26
|
self.coords = {
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
source_dim_names["latitude"]: target_coords["lat"],
|
|
28
|
+
source_dim_names["longitude"]: target_coords["lon"],
|
|
36
29
|
}
|
|
37
30
|
|
|
38
|
-
def apply(self,
|
|
31
|
+
def apply(self, da):
|
|
39
32
|
"""Fills missing values and regrids the variable.
|
|
40
33
|
|
|
41
34
|
Parameters
|
|
42
35
|
----------
|
|
43
|
-
|
|
36
|
+
da : xarray.DataArray
|
|
44
37
|
Input data to fill and regrid.
|
|
45
38
|
|
|
46
39
|
Returns
|
|
@@ -48,38 +41,48 @@ class LateralRegrid:
|
|
|
48
41
|
xarray.DataArray
|
|
49
42
|
Regridded data with filled values.
|
|
50
43
|
"""
|
|
51
|
-
regridded =
|
|
44
|
+
regridded = da.interp(self.coords, method="linear").drop_vars(
|
|
52
45
|
list(self.coords.keys())
|
|
53
46
|
)
|
|
54
47
|
return regridded
|
|
55
48
|
|
|
56
49
|
|
|
57
50
|
class VerticalRegrid:
|
|
58
|
-
"""
|
|
51
|
+
"""Interpolates data onto new vertical (depth) coordinates.
|
|
59
52
|
|
|
60
53
|
Parameters
|
|
61
54
|
----------
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
target_depth_coords : xarray.DataArray
|
|
56
|
+
Depth coordinates for the target grid.
|
|
57
|
+
source_depth_coords : xarray.DataArray
|
|
58
|
+
Depth coordinates for the source grid.
|
|
66
59
|
"""
|
|
67
60
|
|
|
68
|
-
def __init__(self,
|
|
69
|
-
"""
|
|
61
|
+
def __init__(self, target_depth_coords, source_depth_coords):
|
|
62
|
+
"""Initialize regridding factors for interpolation.
|
|
70
63
|
|
|
71
64
|
Parameters
|
|
72
65
|
----------
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
target_depth_coords : xarray.DataArray
|
|
67
|
+
Depth coordinates for the target grid.
|
|
68
|
+
source_depth_coords : xarray.DataArray
|
|
69
|
+
Depth coordinates for the source grid.
|
|
70
|
+
|
|
71
|
+
Attributes
|
|
72
|
+
----------
|
|
73
|
+
coeff : xarray.Dataset
|
|
74
|
+
Dataset containing:
|
|
75
|
+
- `is_below` : Boolean mask for depths just below target.
|
|
76
|
+
- `is_above` : Boolean mask for depths just above target.
|
|
77
|
+
- `upper_mask`, `lower_mask` : Masks for valid interpolation bounds.
|
|
78
|
+
- `factor` : Weight for blending values between levels.
|
|
77
79
|
"""
|
|
78
80
|
|
|
79
|
-
self.depth_dim =
|
|
81
|
+
self.depth_dim = source_depth_coords.dims[0]
|
|
82
|
+
source_depth = source_depth_coords
|
|
80
83
|
dims = {"dim": self.depth_dim}
|
|
81
84
|
|
|
82
|
-
dlev =
|
|
85
|
+
dlev = source_depth - target_depth_coords
|
|
83
86
|
is_below = dlev == dlev.where(dlev >= 0).min(**dims)
|
|
84
87
|
is_above = dlev == dlev.where(dlev <= 0).max(**dims)
|
|
85
88
|
p_below = dlev.where(is_below).sum(**dims)
|
|
@@ -138,61 +141,3 @@ class VerticalRegrid:
|
|
|
138
141
|
)
|
|
139
142
|
|
|
140
143
|
return result
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def _lateral_regrid(data, lon, lat, data_vars, var_names):
|
|
144
|
-
"""Laterally regrid specified variables onto new latitude and longitude coordinates.
|
|
145
|
-
|
|
146
|
-
Parameters
|
|
147
|
-
----------
|
|
148
|
-
data : Dataset
|
|
149
|
-
Input data containing the information about source dimensions.
|
|
150
|
-
lon : xarray.DataArray
|
|
151
|
-
Target longitude coordinates.
|
|
152
|
-
lat : xarray.DataArray
|
|
153
|
-
Target latitude coordinates.
|
|
154
|
-
data_vars : dict of str : xarray.DataArray
|
|
155
|
-
Dictionary of variables to regrid.
|
|
156
|
-
var_names : list of str
|
|
157
|
-
Names of variables to regrid.
|
|
158
|
-
|
|
159
|
-
Returns
|
|
160
|
-
-------
|
|
161
|
-
dict of str : xarray.DataArray
|
|
162
|
-
Updated data_vars with regridded variables.
|
|
163
|
-
"""
|
|
164
|
-
lateral_regrid = LateralRegrid(data, lon, lat)
|
|
165
|
-
|
|
166
|
-
for var_name in var_names:
|
|
167
|
-
if var_name in data_vars:
|
|
168
|
-
data_vars[var_name] = lateral_regrid.apply(data_vars[var_name])
|
|
169
|
-
|
|
170
|
-
return data_vars
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
def _vertical_regrid(data, target_depth, data_vars, var_names):
|
|
174
|
-
"""Vertically regrid specified variables onto new depth coordinates.
|
|
175
|
-
|
|
176
|
-
Parameters
|
|
177
|
-
----------
|
|
178
|
-
data : Dataset
|
|
179
|
-
Input dataset containing the variables and source depth information.
|
|
180
|
-
target_depth : xarray.DataArray
|
|
181
|
-
Target depth coordinates for regridding.
|
|
182
|
-
data_vars : dict of str : xarray.DataArray
|
|
183
|
-
Dictionary of variables to be regridded.
|
|
184
|
-
var_names : list of str
|
|
185
|
-
Names of variables to regrid.
|
|
186
|
-
|
|
187
|
-
Returns
|
|
188
|
-
-------
|
|
189
|
-
dict of str : xarray.DataArray
|
|
190
|
-
Updated data_vars with variables regridded onto the target depth coordinates.
|
|
191
|
-
"""
|
|
192
|
-
vertical_regrid = VerticalRegrid(data, target_depth)
|
|
193
|
-
|
|
194
|
-
for var_name in var_names:
|
|
195
|
-
if var_name in data_vars:
|
|
196
|
-
data_vars[var_name] = vertical_regrid.apply(data_vars[var_name])
|
|
197
|
-
|
|
198
|
-
return data_vars
|
|
@@ -7,8 +7,7 @@ from roms_tools.setup.grid import Grid
|
|
|
7
7
|
from datetime import datetime
|
|
8
8
|
import numpy as np
|
|
9
9
|
from typing import Dict, Union, List
|
|
10
|
-
from roms_tools.setup.
|
|
11
|
-
from roms_tools.setup.regrid import _lateral_regrid, LateralRegrid
|
|
10
|
+
from roms_tools.setup.regrid import LateralRegrid
|
|
12
11
|
from roms_tools.setup.datasets import (
|
|
13
12
|
ERA5Dataset,
|
|
14
13
|
ERA5Correction,
|
|
@@ -99,51 +98,40 @@ class SurfaceForcing:
|
|
|
99
98
|
|
|
100
99
|
data = self._get_data()
|
|
101
100
|
data.choose_subdomain(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
target_coords["lat"].max().values,
|
|
105
|
-
],
|
|
106
|
-
longitude_range=[
|
|
107
|
-
target_coords["lon"].min().values,
|
|
108
|
-
target_coords["lon"].max().values,
|
|
109
|
-
],
|
|
110
|
-
margin=2,
|
|
111
|
-
straddle=target_coords["straddle"],
|
|
101
|
+
target_coords,
|
|
102
|
+
buffer_points=20, # lateral fill needs some buffer from data margin
|
|
112
103
|
)
|
|
113
104
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
data_vars = {}
|
|
117
|
-
for var_name in data.var_names:
|
|
118
|
-
if var_name != "mask":
|
|
119
|
-
data_vars[var_name] = data.ds[data.var_names[var_name]]
|
|
105
|
+
data.apply_lateral_fill()
|
|
120
106
|
|
|
121
|
-
|
|
107
|
+
variable_info = self._set_variable_info(data)
|
|
108
|
+
var_names = variable_info.keys()
|
|
122
109
|
|
|
110
|
+
processed_fields = {}
|
|
123
111
|
# lateral regridding
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
112
|
+
lateral_regrid = LateralRegrid(target_coords, data.dim_names)
|
|
113
|
+
for var_name in var_names:
|
|
114
|
+
if var_name in data.var_names.keys():
|
|
115
|
+
processed_fields[var_name] = lateral_regrid.apply(
|
|
116
|
+
data.ds[data.var_names[var_name]]
|
|
117
|
+
)
|
|
128
118
|
|
|
129
119
|
# rotation of velocities and interpolation to u/v points
|
|
130
120
|
if "uwnd" in variable_info and "vwnd" in variable_info:
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
121
|
+
processed_fields["uwnd"], processed_fields["vwnd"] = rotate_velocities(
|
|
122
|
+
processed_fields["uwnd"],
|
|
123
|
+
processed_fields["vwnd"],
|
|
134
124
|
target_coords["angle"],
|
|
135
125
|
interpolate=False,
|
|
136
126
|
)
|
|
137
127
|
|
|
138
128
|
# correct radiation
|
|
139
129
|
if self.type == "physics" and self.correct_radiation:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
object.__setattr__(data, "data_vars", data_vars)
|
|
130
|
+
processed_fields = self._apply_correction(processed_fields, data)
|
|
143
131
|
|
|
144
132
|
d_meta = get_variable_metadata()
|
|
145
133
|
|
|
146
|
-
ds = self._write_into_dataset(data, d_meta)
|
|
134
|
+
ds = self._write_into_dataset(processed_fields, data, d_meta)
|
|
147
135
|
|
|
148
136
|
if self.use_coarse_grid:
|
|
149
137
|
mask = self.grid.ds["mask_coarse"].rename(
|
|
@@ -152,13 +140,11 @@ class SurfaceForcing:
|
|
|
152
140
|
else:
|
|
153
141
|
mask = self.grid.ds["mask_rho"]
|
|
154
142
|
|
|
155
|
-
|
|
156
|
-
for var in ds.data_vars:
|
|
157
|
-
nan_check(ds[var].isel(time=0), mask)
|
|
143
|
+
self._validate(ds, mask)
|
|
158
144
|
|
|
159
145
|
# substitute NaNs over land by a fill value to avoid blow-up of ROMS
|
|
160
|
-
for
|
|
161
|
-
ds[
|
|
146
|
+
for var_name in ds.data_vars:
|
|
147
|
+
ds[var_name] = substitute_nans_by_fillvalue(ds[var_name])
|
|
162
148
|
|
|
163
149
|
object.__setattr__(self, "ds", ds)
|
|
164
150
|
|
|
@@ -272,7 +258,7 @@ class SurfaceForcing:
|
|
|
272
258
|
|
|
273
259
|
return variable_info
|
|
274
260
|
|
|
275
|
-
def _apply_correction(self,
|
|
261
|
+
def _apply_correction(self, processed_fields, data):
|
|
276
262
|
|
|
277
263
|
correction_data = self._get_correction_data()
|
|
278
264
|
# choose same subdomain as forcing data so that we can use same mask
|
|
@@ -285,44 +271,34 @@ class SurfaceForcing:
|
|
|
285
271
|
correction_data.choose_subdomain(
|
|
286
272
|
coords_correction, straddle=self.target_coords["straddle"]
|
|
287
273
|
)
|
|
288
|
-
|
|
274
|
+
correction_data.ds["mask"] = data.ds["mask"] # use mask from ERA5 data
|
|
275
|
+
correction_data.apply_lateral_fill()
|
|
289
276
|
# regrid
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
[
|
|
293
|
-
correction_data.dim_names["latitude"],
|
|
294
|
-
correction_data.dim_names["longitude"],
|
|
295
|
-
],
|
|
296
|
-
)
|
|
297
|
-
lateral_regrid = LateralRegrid(
|
|
298
|
-
correction_data, self.target_coords["lon"], self.target_coords["lat"]
|
|
299
|
-
)
|
|
300
|
-
|
|
301
|
-
filled = lateral_fill.apply(
|
|
277
|
+
lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
|
|
278
|
+
corr_factor = lateral_regrid.apply(
|
|
302
279
|
correction_data.ds[correction_data.var_names["swr_corr"]]
|
|
303
280
|
)
|
|
304
|
-
corr_factor = lateral_regrid.apply(filled)
|
|
305
281
|
|
|
306
282
|
# temporal interpolation
|
|
307
283
|
corr_factor = interpolate_from_climatology(
|
|
308
284
|
corr_factor,
|
|
309
285
|
correction_data.dim_names["time"],
|
|
310
|
-
time=
|
|
286
|
+
time=processed_fields["swrad"].time,
|
|
311
287
|
)
|
|
312
288
|
|
|
313
|
-
|
|
289
|
+
processed_fields["swrad"] = processed_fields["swrad"] * corr_factor
|
|
314
290
|
|
|
315
|
-
return
|
|
291
|
+
return processed_fields
|
|
316
292
|
|
|
317
|
-
def _write_into_dataset(self, data, d_meta):
|
|
293
|
+
def _write_into_dataset(self, processed_fields, data, d_meta):
|
|
318
294
|
|
|
319
295
|
# save in new dataset
|
|
320
296
|
ds = xr.Dataset()
|
|
321
297
|
|
|
322
|
-
for
|
|
323
|
-
ds[
|
|
324
|
-
ds[
|
|
325
|
-
ds[
|
|
298
|
+
for var_name in processed_fields.keys():
|
|
299
|
+
ds[var_name] = processed_fields[var_name].astype(np.float32)
|
|
300
|
+
ds[var_name].attrs["long_name"] = d_meta[var_name]["long_name"]
|
|
301
|
+
ds[var_name].attrs["units"] = d_meta[var_name]["units"]
|
|
326
302
|
|
|
327
303
|
if self.use_coarse_grid:
|
|
328
304
|
ds = ds.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"})
|
|
@@ -388,11 +364,36 @@ class SurfaceForcing:
|
|
|
388
364
|
ds = ds.drop_vars(["time"])
|
|
389
365
|
|
|
390
366
|
variables_to_drop = ["lat_rho", "lon_rho", "lat_coarse", "lon_coarse"]
|
|
391
|
-
existing_vars = [
|
|
367
|
+
existing_vars = [var_name for var_name in variables_to_drop if var_name in ds]
|
|
392
368
|
ds = ds.drop_vars(existing_vars)
|
|
393
369
|
|
|
394
370
|
return ds
|
|
395
371
|
|
|
372
|
+
def _validate(self, ds, mask):
|
|
373
|
+
"""Validates the dataset by checking for NaN values at wet points, which would
|
|
374
|
+
indicate missing raw data coverage over the target domain.
|
|
375
|
+
|
|
376
|
+
Parameters
|
|
377
|
+
----------
|
|
378
|
+
ds : xarray.Dataset
|
|
379
|
+
The dataset to validate.
|
|
380
|
+
mask : xarray.DataArray
|
|
381
|
+
Land mask (1=ocean, 0=land) to determine wet points in the domain.
|
|
382
|
+
|
|
383
|
+
Raises
|
|
384
|
+
------
|
|
385
|
+
ValueError
|
|
386
|
+
If NaN values are found in any of the specified variables at wet points,
|
|
387
|
+
indicating incomplete data coverage.
|
|
388
|
+
|
|
389
|
+
Notes
|
|
390
|
+
-----
|
|
391
|
+
This check is applied to the first time step (`time=0`) of each variable in the provided dataset.
|
|
392
|
+
"""
|
|
393
|
+
|
|
394
|
+
for var_name in ds.data_vars:
|
|
395
|
+
nan_check(ds[var_name].isel(time=0), mask)
|
|
396
|
+
|
|
396
397
|
def _add_global_metadata(self, ds=None):
|
|
397
398
|
|
|
398
399
|
if ds is None:
|
|
@@ -416,12 +417,12 @@ class SurfaceForcing:
|
|
|
416
417
|
|
|
417
418
|
return ds
|
|
418
419
|
|
|
419
|
-
def plot(self,
|
|
420
|
+
def plot(self, var_name, time=0) -> None:
|
|
420
421
|
"""Plot the specified surface forcing field for a given time slice.
|
|
421
422
|
|
|
422
423
|
Parameters
|
|
423
424
|
----------
|
|
424
|
-
|
|
425
|
+
var_name : str
|
|
425
426
|
The name of the surface forcing field to plot. Options include:
|
|
426
427
|
|
|
427
428
|
- "uwnd": 10 meter wind in x-direction.
|
|
@@ -450,7 +451,7 @@ class SurfaceForcing:
|
|
|
450
451
|
Raises
|
|
451
452
|
------
|
|
452
453
|
ValueError
|
|
453
|
-
If the specified
|
|
454
|
+
If the specified var_name is not found in dataset.
|
|
454
455
|
|
|
455
456
|
|
|
456
457
|
Examples
|
|
@@ -458,10 +459,10 @@ class SurfaceForcing:
|
|
|
458
459
|
>>> atm_forcing.plot("uwnd", time=0)
|
|
459
460
|
"""
|
|
460
461
|
|
|
461
|
-
if
|
|
462
|
-
raise ValueError(f"Variable '{
|
|
462
|
+
if var_name not in self.ds:
|
|
463
|
+
raise ValueError(f"Variable '{var_name}' is not found in dataset.")
|
|
463
464
|
|
|
464
|
-
field = self.ds[
|
|
465
|
+
field = self.ds[var_name].isel(time=time).load()
|
|
465
466
|
title = field.long_name
|
|
466
467
|
|
|
467
468
|
# assign lat / lon
|
|
@@ -476,14 +477,14 @@ class SurfaceForcing:
|
|
|
476
477
|
)
|
|
477
478
|
|
|
478
479
|
# choose colorbar
|
|
479
|
-
if
|
|
480
|
+
if var_name in ["uwnd", "vwnd"]:
|
|
480
481
|
vmax = max(field.max().values, -field.min().values)
|
|
481
482
|
vmin = -vmax
|
|
482
483
|
cmap = plt.colormaps.get_cmap("RdBu_r")
|
|
483
484
|
else:
|
|
484
485
|
vmax = field.max().values
|
|
485
486
|
vmin = field.min().values
|
|
486
|
-
if
|
|
487
|
+
if var_name in ["swrad", "lwrad", "Tair", "qair"]:
|
|
487
488
|
cmap = plt.colormaps.get_cmap("YlOrRd")
|
|
488
489
|
else:
|
|
489
490
|
cmap = plt.colormaps.get_cmap("YlGnBu")
|
roms_tools/setup/tides.py
CHANGED
|
@@ -20,8 +20,7 @@ from roms_tools.setup.utils import (
|
|
|
20
20
|
rotate_velocities,
|
|
21
21
|
get_vector_pairs,
|
|
22
22
|
)
|
|
23
|
-
from roms_tools.setup.
|
|
24
|
-
from roms_tools.setup.regrid import _lateral_regrid
|
|
23
|
+
from roms_tools.setup.regrid import LateralRegrid
|
|
25
24
|
import matplotlib.pyplot as plt
|
|
26
25
|
from pathlib import Path
|
|
27
26
|
|
|
@@ -77,71 +76,64 @@ class TidalForcing:
|
|
|
77
76
|
data = self._get_data()
|
|
78
77
|
data.check_number_constituents(self.ntides)
|
|
79
78
|
data.choose_subdomain(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
target_coords["lat"].max().values,
|
|
83
|
-
],
|
|
84
|
-
longitude_range=[
|
|
85
|
-
target_coords["lon"].min().values,
|
|
86
|
-
target_coords["lon"].max().values,
|
|
87
|
-
],
|
|
88
|
-
margin=2,
|
|
89
|
-
straddle=target_coords["straddle"],
|
|
79
|
+
target_coords,
|
|
80
|
+
buffer_points=20,
|
|
90
81
|
)
|
|
91
82
|
# select desired number of constituents
|
|
92
83
|
object.__setattr__(data, "ds", data.ds.isel(ntides=slice(None, self.ntides)))
|
|
93
84
|
self._correct_tides(data)
|
|
94
85
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
data_vars = {}
|
|
98
|
-
for var_name in data.var_names:
|
|
99
|
-
data_vars[var_name] = data.ds[data.var_names[var_name]]
|
|
86
|
+
data.apply_lateral_fill()
|
|
100
87
|
|
|
101
|
-
|
|
88
|
+
variable_info = self._set_variable_info()
|
|
89
|
+
var_names = variable_info.keys()
|
|
102
90
|
|
|
91
|
+
processed_fields = {}
|
|
103
92
|
# lateral regridding
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
lateral_regrid = LateralRegrid(target_coords, data.dim_names)
|
|
94
|
+
for var_name in var_names:
|
|
95
|
+
if var_name in data.var_names.keys():
|
|
96
|
+
processed_fields[var_name] = lateral_regrid.apply(
|
|
97
|
+
data.ds[data.var_names[var_name]]
|
|
98
|
+
)
|
|
108
99
|
|
|
109
100
|
# rotation of velocities and interpolation to u/v points
|
|
110
101
|
vector_pairs = get_vector_pairs(variable_info)
|
|
111
102
|
for pair in vector_pairs:
|
|
112
103
|
u_component = pair[0]
|
|
113
104
|
v_component = pair[1]
|
|
114
|
-
if u_component in
|
|
115
|
-
(
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
if u_component in processed_fields and v_component in processed_fields:
|
|
106
|
+
(
|
|
107
|
+
processed_fields[u_component],
|
|
108
|
+
processed_fields[v_component],
|
|
109
|
+
) = rotate_velocities(
|
|
110
|
+
processed_fields[u_component],
|
|
111
|
+
processed_fields[v_component],
|
|
118
112
|
target_coords["angle"],
|
|
119
113
|
interpolate=False,
|
|
120
114
|
)
|
|
121
115
|
|
|
122
116
|
# convert to barotropic velocity
|
|
123
|
-
for
|
|
124
|
-
|
|
117
|
+
for var_name in ["u_Re", "v_Re", "u_Im", "v_Im"]:
|
|
118
|
+
processed_fields[var_name] = processed_fields[var_name] / self.grid.ds.h
|
|
125
119
|
|
|
126
120
|
# interpolate from rho- to velocity points
|
|
127
121
|
for uname in ["u_Re", "u_Im"]:
|
|
128
|
-
|
|
122
|
+
processed_fields[uname] = interpolate_from_rho_to_u(processed_fields[uname])
|
|
129
123
|
for vname in ["v_Re", "v_Im"]:
|
|
130
|
-
|
|
124
|
+
processed_fields[vname] = interpolate_from_rho_to_v(processed_fields[vname])
|
|
131
125
|
|
|
132
126
|
d_meta = get_variable_metadata()
|
|
133
|
-
ds = self._write_into_dataset(
|
|
127
|
+
ds = self._write_into_dataset(processed_fields, d_meta)
|
|
134
128
|
ds["omega"] = data.ds["omega"]
|
|
135
129
|
|
|
136
130
|
ds = self._add_global_metadata(ds)
|
|
137
131
|
|
|
138
|
-
|
|
139
|
-
for var in ["ssh_Re", "u_Re", "v_Im"]:
|
|
140
|
-
nan_check(ds[var].isel(ntides=0), self.grid.ds.mask_rho)
|
|
132
|
+
self._validate(ds)
|
|
141
133
|
|
|
142
134
|
# substitute NaNs over land by a fill value to avoid blow-up of ROMS
|
|
143
|
-
for
|
|
144
|
-
ds[
|
|
135
|
+
for var_name in ds.data_vars:
|
|
136
|
+
ds[var_name] = substitute_nans_by_fillvalue(ds[var_name])
|
|
145
137
|
|
|
146
138
|
object.__setattr__(self, "ds", ds)
|
|
147
139
|
|
|
@@ -216,15 +208,15 @@ class TidalForcing:
|
|
|
216
208
|
|
|
217
209
|
return variable_info
|
|
218
210
|
|
|
219
|
-
def _write_into_dataset(self,
|
|
211
|
+
def _write_into_dataset(self, processed_fields, d_meta):
|
|
220
212
|
|
|
221
213
|
# save in new dataset
|
|
222
214
|
ds = xr.Dataset()
|
|
223
215
|
|
|
224
|
-
for
|
|
225
|
-
ds[
|
|
226
|
-
ds[
|
|
227
|
-
ds[
|
|
216
|
+
for var_name in processed_fields.keys():
|
|
217
|
+
ds[var_name] = processed_fields[var_name].astype(np.float32)
|
|
218
|
+
ds[var_name].attrs["long_name"] = d_meta[var_name]["long_name"]
|
|
219
|
+
ds[var_name].attrs["units"] = d_meta[var_name]["units"]
|
|
228
220
|
|
|
229
221
|
ds = ds.drop_vars(["lat_rho", "lon_rho"])
|
|
230
222
|
|
|
@@ -247,12 +239,35 @@ class TidalForcing:
|
|
|
247
239
|
|
|
248
240
|
return ds
|
|
249
241
|
|
|
250
|
-
def
|
|
242
|
+
def _validate(self, ds):
|
|
243
|
+
"""Validates the dataset by checking for NaN values at wet points, which would
|
|
244
|
+
indicate missing raw data coverage over the target domain.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
ds : xarray.Dataset
|
|
249
|
+
The dataset to validate, containing tidal variables and a mask for wet points.
|
|
250
|
+
|
|
251
|
+
Raises
|
|
252
|
+
------
|
|
253
|
+
ValueError
|
|
254
|
+
If NaN values are found in any of the specified variables at wet points,
|
|
255
|
+
indicating incomplete data coverage.
|
|
256
|
+
|
|
257
|
+
Notes
|
|
258
|
+
-----
|
|
259
|
+
This check is applied to the first constituent (`ntides=0`) of each variable in the dataset.
|
|
260
|
+
The method utilizes `self.grid.ds.mask_rho` to determine the wet points in the domain.
|
|
261
|
+
"""
|
|
262
|
+
for var_name in ds.data_vars:
|
|
263
|
+
nan_check(ds[var_name].isel(ntides=0), self.grid.ds.mask_rho)
|
|
264
|
+
|
|
265
|
+
def plot(self, var_name, ntides=0) -> None:
|
|
251
266
|
"""Plot the specified tidal forcing variable for a given tidal constituent.
|
|
252
267
|
|
|
253
268
|
Parameters
|
|
254
269
|
----------
|
|
255
|
-
|
|
270
|
+
var_name : str
|
|
256
271
|
The tidal forcing variable to plot. Options include:
|
|
257
272
|
|
|
258
273
|
- "ssh_Re": Real part of tidal elevation.
|
|
@@ -285,7 +300,7 @@ class TidalForcing:
|
|
|
285
300
|
>>> tidal_forcing.plot("ssh_Re", nc=0)
|
|
286
301
|
"""
|
|
287
302
|
|
|
288
|
-
field = self.ds[
|
|
303
|
+
field = self.ds[var_name].isel(ntides=ntides).compute()
|
|
289
304
|
if all(dim in field.dims for dim in ["eta_rho", "xi_rho"]):
|
|
290
305
|
field = field.where(self.grid.ds.mask_rho)
|
|
291
306
|
field = field.assign_coords(
|
|
@@ -306,7 +321,7 @@ class TidalForcing:
|
|
|
306
321
|
else:
|
|
307
322
|
ValueError("provided field does not have two horizontal dimension")
|
|
308
323
|
|
|
309
|
-
title = "%s, ntides = %i" % (field.long_name, self.ds[
|
|
324
|
+
title = "%s, ntides = %i" % (field.long_name, self.ds[var_name].ntides[ntides])
|
|
310
325
|
|
|
311
326
|
vmax = max(field.max(), -field.min())
|
|
312
327
|
vmin = -vmax
|