roms-tools 2.3.0__py3-none-any.whl → 2.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.
- ci/environment.yml +1 -0
- roms_tools/__init__.py +2 -1
- roms_tools/analysis/roms_output.py +81 -98
- roms_tools/plot.py +4 -2
- roms_tools/setup/boundary_forcing.py +207 -208
- roms_tools/setup/datasets.py +149 -33
- roms_tools/setup/grid.py +35 -102
- roms_tools/setup/initial_conditions.py +179 -132
- roms_tools/setup/nesting.py +239 -86
- roms_tools/setup/river_forcing.py +266 -128
- roms_tools/setup/surface_forcing.py +137 -76
- roms_tools/setup/tides.py +10 -36
- roms_tools/setup/topography.py +25 -2
- roms_tools/setup/utils.py +52 -82
- roms_tools/tests/test_analysis/test_roms_output.py +233 -70
- roms_tools/tests/test_setup/test_boundary_forcing.py +283 -57
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zattrs +3 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/.zmetadata +3 -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_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_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_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_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 +2 -2
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/.zmetadata +8 -7
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing.zarr/abs_time/.zattrs +1 -0
- 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/dust_time/.zattrs +1 -1
- 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/iron_time/.zattrs +1 -1
- 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/nhy_time/.zattrs +1 -1
- 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/nox_time/.zattrs +1 -1
- 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.zarr/pco2_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zattrs +2 -2
- roms_tools/tests/test_setup/test_data/bgc_surface_forcing_from_climatology.zarr/.zmetadata +2 -2
- 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/.zattrs +5 -3
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/.zmetadata +156 -121
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/.zattrs +2 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/abs_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/bry_time/0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/salt_east/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- 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/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_east/.zattrs +8 -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/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_north/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_south/.zattrs +8 -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/.zarray +4 -4
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/boundary_forcing.zarr/zeta_west/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +2 -2
- roms_tools/tests/test_setup/test_data/grid.zarr/angle/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/angle_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/f/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/h/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/h/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/lat_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/lat_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/lat_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/lat_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/pm/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +4 -4
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +4 -4
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/angle_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/f/0.0 +0 -0
- 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/lat_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lat_v/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_coarse/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_rho/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_u/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/lon_v/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_that_straddles_dateline.zarr/pm/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/pn/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zattrs +2 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/.zmetadata +6 -4
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/Cs_w/.zattrs +1 -1
- 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/PO4/0.0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_with_bgc_from_climatology.zarr/abs_time/.zattrs +1 -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/ocean_time/.zattrs +1 -1
- 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/spFe/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/river_forcing_no_climatology.zarr/.zmetadata +56 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/nriver/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_location/0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/.zmetadata +56 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/.zattrs +6 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/nriver/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zarray +22 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/.zattrs +8 -0
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_location/0.0 +0 -0
- roms_tools/tests/test_setup/test_grid.py +0 -13
- roms_tools/tests/test_setup/test_initial_conditions.py +220 -66
- roms_tools/tests/test_setup/test_nesting.py +139 -118
- roms_tools/tests/test_setup/test_river_forcing.py +583 -293
- roms_tools/tests/test_setup/test_surface_forcing.py +149 -73
- roms_tools/tests/test_setup/test_tides.py +4 -16
- roms_tools/tests/test_setup/test_utils.py +1 -0
- roms_tools/tests/test_setup/test_validation.py +34 -2
- roms_tools/tests/{test_utils.py → test_tiling/test_partition.py} +1 -1
- roms_tools/tiling/partition.py +338 -0
- roms_tools/utils.py +66 -333
- roms_tools/vertical_coordinate.py +54 -133
- {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/METADATA +1 -1
- {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/RECORD +303 -290
- {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/WHEEL +1 -1
- {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/LICENSE +0 -0
- {roms_tools-2.3.0.dist-info → roms_tools-2.5.0.dist-info}/top_level.txt +0 -0
|
@@ -5,8 +5,10 @@ from datetime import datetime
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import matplotlib.pyplot as plt
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Dict, Union, List, Optional
|
|
9
10
|
from roms_tools import Grid
|
|
11
|
+
from roms_tools.utils import save_datasets
|
|
10
12
|
from roms_tools.regrid import LateralRegrid
|
|
11
13
|
from roms_tools.plot import _plot
|
|
12
14
|
from roms_tools.setup.datasets import (
|
|
@@ -21,7 +23,6 @@ from roms_tools.setup.utils import (
|
|
|
21
23
|
interpolate_from_climatology,
|
|
22
24
|
get_variable_metadata,
|
|
23
25
|
group_dataset,
|
|
24
|
-
save_datasets,
|
|
25
26
|
rotate_velocities,
|
|
26
27
|
convert_to_roms_time,
|
|
27
28
|
_to_yaml,
|
|
@@ -37,10 +38,14 @@ class SurfaceForcing:
|
|
|
37
38
|
----------
|
|
38
39
|
grid : Grid
|
|
39
40
|
Object representing the grid information.
|
|
40
|
-
start_time : datetime
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
start_time : datetime, optional
|
|
42
|
+
The start time of the desired surface forcing data. This time is used to filter the dataset
|
|
43
|
+
to include only records on or after this time, with a single record at or before this time.
|
|
44
|
+
If no time filtering is desired, set it to None. Default is None.
|
|
45
|
+
end_time : datetime, optional
|
|
46
|
+
The end time of the desired surface forcing data. This time is used to filter the dataset
|
|
47
|
+
to include only records on or before this time, with a single record at or after this time.
|
|
48
|
+
If no time filtering is desired, set it to None. Default is None.
|
|
44
49
|
source : Dict[str, Union[str, Path, List[Union[str, Path]]], bool]
|
|
45
50
|
Dictionary specifying the source of the surface forcing data. Keys include:
|
|
46
51
|
|
|
@@ -59,9 +64,14 @@ class SurfaceForcing:
|
|
|
59
64
|
- "bgc": for biogeochemical forcing.
|
|
60
65
|
|
|
61
66
|
correct_radiation : bool
|
|
62
|
-
Whether to correct shortwave radiation. Default is
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
Whether to correct shortwave radiation. Default is True.
|
|
68
|
+
coarse_grid_mode : str, optional
|
|
69
|
+
Specifies whether to interpolate onto grid coarsened by a factor of two. Options are:
|
|
70
|
+
|
|
71
|
+
- "auto" (default): Automatically decide based on the comparison of source and target spatial resolutions.
|
|
72
|
+
- "always": Always interpolate onto the coarse grid.
|
|
73
|
+
- "never": Never use the coarse grid; interpolate onto the fine grid instead.
|
|
74
|
+
|
|
65
75
|
model_reference_date : datetime, optional
|
|
66
76
|
Reference date for the model. Default is January 1, 2000.
|
|
67
77
|
use_dask: bool, optional
|
|
@@ -84,12 +94,12 @@ class SurfaceForcing:
|
|
|
84
94
|
"""
|
|
85
95
|
|
|
86
96
|
grid: Grid
|
|
87
|
-
start_time: datetime
|
|
88
|
-
end_time: datetime
|
|
97
|
+
start_time: Optional[datetime] = None
|
|
98
|
+
end_time: Optional[datetime] = None
|
|
89
99
|
source: Dict[str, Union[str, Path, List[Union[str, Path]]]]
|
|
90
100
|
type: str = "physics"
|
|
91
|
-
correct_radiation: bool =
|
|
92
|
-
|
|
101
|
+
correct_radiation: bool = True
|
|
102
|
+
coarse_grid_mode: str = "auto"
|
|
93
103
|
model_reference_date: datetime = datetime(2000, 1, 1)
|
|
94
104
|
use_dask: bool = False
|
|
95
105
|
bypass_validation: bool = False
|
|
@@ -99,14 +109,29 @@ class SurfaceForcing:
|
|
|
99
109
|
def __post_init__(self):
|
|
100
110
|
|
|
101
111
|
self._input_checks()
|
|
112
|
+
data = self._get_data()
|
|
113
|
+
|
|
114
|
+
if self.coarse_grid_mode == "always":
|
|
115
|
+
use_coarse_grid = True
|
|
116
|
+
elif self.coarse_grid_mode == "never":
|
|
117
|
+
use_coarse_grid = False
|
|
118
|
+
elif self.coarse_grid_mode == "auto":
|
|
119
|
+
use_coarse_grid = self._determine_coarse_grid_usage(data)
|
|
120
|
+
if use_coarse_grid:
|
|
121
|
+
logging.info("Data will be interpolated onto grid coarsened by factor 2.")
|
|
122
|
+
else:
|
|
123
|
+
logging.info("Data will be interpolated onto fine grid.")
|
|
124
|
+
object.__setattr__(self, "use_coarse_grid", use_coarse_grid)
|
|
125
|
+
|
|
102
126
|
target_coords = get_target_coords(self.grid, self.use_coarse_grid)
|
|
103
127
|
object.__setattr__(self, "target_coords", target_coords)
|
|
104
128
|
|
|
105
|
-
data = self._get_data()
|
|
106
129
|
data.choose_subdomain(
|
|
107
130
|
target_coords,
|
|
108
131
|
buffer_points=20, # lateral fill needs some buffer from data margin
|
|
109
132
|
)
|
|
133
|
+
# Enforce double precision to ensure reproducibility
|
|
134
|
+
data.convert_to_float64()
|
|
110
135
|
|
|
111
136
|
data.apply_lateral_fill()
|
|
112
137
|
|
|
@@ -149,6 +174,18 @@ class SurfaceForcing:
|
|
|
149
174
|
object.__setattr__(self, "ds", ds)
|
|
150
175
|
|
|
151
176
|
def _input_checks(self):
|
|
177
|
+
# Check that start_time and end_time are both None or none of them is
|
|
178
|
+
if (self.start_time is None) != (self.end_time is None):
|
|
179
|
+
raise ValueError(
|
|
180
|
+
"Both `start_time` and `end_time` must be provided together as datetime objects or both should be None."
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Trigger a warning if both are None
|
|
184
|
+
if self.start_time is None and self.end_time is None:
|
|
185
|
+
logging.warning(
|
|
186
|
+
"Both `start_time` and `end_time` are None. No time filtering will be applied to the source data."
|
|
187
|
+
)
|
|
188
|
+
|
|
152
189
|
# Validate the 'type' parameter
|
|
153
190
|
if self.type not in ["physics", "bgc"]:
|
|
154
191
|
raise ValueError("`type` must be either 'physics' or 'bgc'.")
|
|
@@ -166,6 +203,47 @@ class SurfaceForcing:
|
|
|
166
203
|
{**self.source, "climatology": self.source.get("climatology", False)},
|
|
167
204
|
)
|
|
168
205
|
|
|
206
|
+
# Validate 'coarse_grid_mode'
|
|
207
|
+
valid_modes = ["auto", "always", "never"]
|
|
208
|
+
if self.coarse_grid_mode not in valid_modes:
|
|
209
|
+
raise ValueError(
|
|
210
|
+
f"`coarse_grid_mode` must be one of {valid_modes}, but got '{self.coarse_grid_mode}'."
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
def _determine_coarse_grid_usage(self, data):
|
|
214
|
+
"""Determine if coarse grid interpolation should be used based on the resolution
|
|
215
|
+
of the dataset and the target grid.
|
|
216
|
+
|
|
217
|
+
Parameters
|
|
218
|
+
----------
|
|
219
|
+
data : object
|
|
220
|
+
The dataset object containing the data to be analyzed for grid spacing.
|
|
221
|
+
|
|
222
|
+
Returns
|
|
223
|
+
-------
|
|
224
|
+
use_coarse_grid : bool
|
|
225
|
+
Whether to use the coarse grid or not.
|
|
226
|
+
"""
|
|
227
|
+
# Get the target coordinates and select the subdomain of the data
|
|
228
|
+
target_coords = get_target_coords(self.grid, use_coarse_grid=False)
|
|
229
|
+
data_coords = data.choose_subdomain(
|
|
230
|
+
target_coords, buffer_points=1, return_coords_only=True
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Compute minimal grid spacing in the data subdomain
|
|
234
|
+
min_grid_spacing_data = data.compute_minimal_grid_spacing(data_coords)
|
|
235
|
+
|
|
236
|
+
# Compute the maximum grid spacing in the ROMS grid
|
|
237
|
+
max_grid_spacing = max((1 / self.grid.ds.pm).max(), (1 / self.grid.ds.pn).max())
|
|
238
|
+
|
|
239
|
+
# Determine whether to use coarse grid based on grid spacing comparison
|
|
240
|
+
if 2 * max_grid_spacing < min_grid_spacing_data:
|
|
241
|
+
use_coarse_grid = True
|
|
242
|
+
else:
|
|
243
|
+
use_coarse_grid = False
|
|
244
|
+
|
|
245
|
+
return use_coarse_grid
|
|
246
|
+
|
|
169
247
|
def _get_data(self):
|
|
170
248
|
|
|
171
249
|
data_dict = {
|
|
@@ -238,14 +316,14 @@ class SurfaceForcing:
|
|
|
238
316
|
"qair": {**default_info, "validate": True},
|
|
239
317
|
"rain": {**default_info, "validate": False},
|
|
240
318
|
"uwnd": {
|
|
241
|
-
"location": "
|
|
319
|
+
"location": "rho",
|
|
242
320
|
"is_vector": True,
|
|
243
321
|
"vector_pair": "vwnd",
|
|
244
322
|
"is_3d": False,
|
|
245
323
|
"validate": True,
|
|
246
324
|
},
|
|
247
325
|
"vwnd": {
|
|
248
|
-
"location": "
|
|
326
|
+
"location": "rho",
|
|
249
327
|
"is_vector": True,
|
|
250
328
|
"vector_pair": "uwnd",
|
|
251
329
|
"is_3d": False,
|
|
@@ -266,7 +344,7 @@ class SurfaceForcing:
|
|
|
266
344
|
def _apply_correction(self, processed_fields, data):
|
|
267
345
|
|
|
268
346
|
correction_data = self._get_correction_data()
|
|
269
|
-
#
|
|
347
|
+
# Match subdomain to forcing data to reuse the mask
|
|
270
348
|
coords_correction = {
|
|
271
349
|
"lat": data.ds[data.dim_names["latitude"]],
|
|
272
350
|
"lon": data.ds[data.dim_names["longitude"]],
|
|
@@ -275,23 +353,39 @@ class SurfaceForcing:
|
|
|
275
353
|
coords_correction, straddle=self.target_coords["straddle"]
|
|
276
354
|
)
|
|
277
355
|
correction_data.ds["mask"] = data.ds["mask"] # use mask from ERA5 data
|
|
356
|
+
correction_data.ds["time"] = correction_data.ds["time"].dt.days
|
|
357
|
+
|
|
278
358
|
correction_data.apply_lateral_fill()
|
|
279
|
-
# regrid
|
|
280
|
-
lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
|
|
281
|
-
corr_factor = lateral_regrid.apply(
|
|
282
|
-
correction_data.ds[correction_data.var_names["swr_corr"]]
|
|
283
|
-
)
|
|
284
359
|
|
|
285
|
-
#
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
time
|
|
290
|
-
|
|
360
|
+
# Temporal interpolation: Perform before spatial regridding for better performance
|
|
361
|
+
if self.use_dask:
|
|
362
|
+
# Perform temporal interpolation for each time slice to enforce chunking in time.
|
|
363
|
+
# This reduces memory usage by processing one time step at a time.
|
|
364
|
+
# The interpolated slices are then concatenated along the "time" dimension.
|
|
365
|
+
corr_factor = xr.concat(
|
|
366
|
+
[
|
|
367
|
+
interpolate_from_climatology(
|
|
368
|
+
correction_data.ds[correction_data.var_names["swr_corr"]],
|
|
369
|
+
correction_data.dim_names["time"],
|
|
370
|
+
time=time,
|
|
371
|
+
)
|
|
372
|
+
for time in processed_fields["swrad"].time
|
|
373
|
+
],
|
|
374
|
+
dim="time",
|
|
375
|
+
)
|
|
376
|
+
else:
|
|
377
|
+
# Interpolate across all time steps at once
|
|
378
|
+
corr_factor = interpolate_from_climatology(
|
|
379
|
+
correction_data.ds[correction_data.var_names["swr_corr"]],
|
|
380
|
+
correction_data.dim_names["time"],
|
|
381
|
+
time=processed_fields["swrad"].time,
|
|
382
|
+
)
|
|
291
383
|
|
|
292
|
-
|
|
384
|
+
# Spatial regridding
|
|
385
|
+
lateral_regrid = LateralRegrid(self.target_coords, correction_data.dim_names)
|
|
386
|
+
corr_factor = lateral_regrid.apply(corr_factor)
|
|
293
387
|
|
|
294
|
-
|
|
388
|
+
processed_fields["swrad"] = processed_fields["swrad"] * corr_factor
|
|
295
389
|
|
|
296
390
|
return processed_fields
|
|
297
391
|
|
|
@@ -357,12 +451,8 @@ class SurfaceForcing:
|
|
|
357
451
|
|
|
358
452
|
for var_name in ds.data_vars:
|
|
359
453
|
if self.variable_info[var_name]["validate"]:
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
elif self.variable_info[var_name]["location"] == "u":
|
|
363
|
-
mask = self.target_coords["mask_u"]
|
|
364
|
-
elif self.variable_info[var_name]["location"] == "v":
|
|
365
|
-
mask = self.target_coords["mask_v"]
|
|
454
|
+
# all variables are at rho-points
|
|
455
|
+
mask = self.target_coords["mask"]
|
|
366
456
|
nan_check(ds[var_name].isel(time=0), mask)
|
|
367
457
|
|
|
368
458
|
def _add_global_metadata(self, ds=None):
|
|
@@ -476,42 +566,26 @@ class SurfaceForcing:
|
|
|
476
566
|
def save(
|
|
477
567
|
self,
|
|
478
568
|
filepath: Union[str, Path],
|
|
479
|
-
|
|
480
|
-
np_xi: int = None,
|
|
481
|
-
group: bool = False,
|
|
569
|
+
group: bool = True,
|
|
482
570
|
) -> None:
|
|
483
571
|
"""Save the surface forcing fields to one or more netCDF4 files.
|
|
484
572
|
|
|
485
|
-
This method saves the dataset
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
1. **Single File Mode (default)**:
|
|
489
|
-
- If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file.
|
|
490
|
-
- The file is named based on the `filepath`, with `.nc` automatically appended.
|
|
491
|
-
|
|
492
|
-
2. **Partitioned Mode**:
|
|
493
|
-
- If either `np_eta` or `np_xi` is specified, the dataset is partitioned into spatial tiles along the `eta` and `xi` axes.
|
|
494
|
-
- Each tile is saved as a separate netCDF4 file, and filenames are modified with an index (e.g., `"filepath_YYYYMM.0.nc"`, `"filepath_YYYYMM.1.nc"`).
|
|
495
|
-
|
|
496
|
-
Additionally, if `group` is set to `True`, the dataset is first grouped into temporal subsets, resulting in multiple grouped files before partitioning and saving.
|
|
573
|
+
This method saves the dataset to disk as either a single netCDF4 file or multiple files, depending on the `group` parameter.
|
|
574
|
+
If `group` is `True`, the dataset is divided into subsets (e.g., monthly or yearly) based on the temporal frequency
|
|
575
|
+
of the data, and each subset is saved to a separate file.
|
|
497
576
|
|
|
498
577
|
Parameters
|
|
499
578
|
----------
|
|
500
579
|
filepath : Union[str, Path]
|
|
501
|
-
The base path and filename for the output
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed.
|
|
506
|
-
np_xi : int, optional
|
|
507
|
-
The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed.
|
|
508
|
-
group: bool, optional
|
|
509
|
-
If `True`, groups the dataset into multiple files based on temporal data frequency. Defaults to `False`.
|
|
580
|
+
The base path and filename for the output file(s). If `group` is `True`, the filenames will include additional
|
|
581
|
+
time-based information (e.g., year or month) to distinguish the subsets.
|
|
582
|
+
group : bool, optional
|
|
583
|
+
Whether to divide the dataset into multiple files based on temporal frequency. Defaults to `True`.
|
|
510
584
|
|
|
511
585
|
Returns
|
|
512
586
|
-------
|
|
513
587
|
List[Path]
|
|
514
|
-
A list of Path objects
|
|
588
|
+
A list of `Path` objects representing the filenames of the saved file(s).
|
|
515
589
|
"""
|
|
516
590
|
|
|
517
591
|
# Ensure filepath is a Path object
|
|
@@ -521,12 +595,6 @@ class SurfaceForcing:
|
|
|
521
595
|
if filepath.suffix == ".nc":
|
|
522
596
|
filepath = filepath.with_suffix("")
|
|
523
597
|
|
|
524
|
-
if self.use_dask:
|
|
525
|
-
from dask.diagnostics import ProgressBar
|
|
526
|
-
|
|
527
|
-
with ProgressBar():
|
|
528
|
-
self.ds.load()
|
|
529
|
-
|
|
530
598
|
if group:
|
|
531
599
|
dataset_list, output_filenames = group_dataset(self.ds, str(filepath))
|
|
532
600
|
else:
|
|
@@ -534,7 +602,7 @@ class SurfaceForcing:
|
|
|
534
602
|
output_filenames = [str(filepath)]
|
|
535
603
|
|
|
536
604
|
saved_filenames = save_datasets(
|
|
537
|
-
dataset_list, output_filenames,
|
|
605
|
+
dataset_list, output_filenames, use_dask=self.use_dask
|
|
538
606
|
)
|
|
539
607
|
|
|
540
608
|
return saved_filenames
|
|
@@ -556,7 +624,6 @@ class SurfaceForcing:
|
|
|
556
624
|
cls,
|
|
557
625
|
filepath: Union[str, Path],
|
|
558
626
|
use_dask: bool = False,
|
|
559
|
-
bypass_validation: bool = False,
|
|
560
627
|
) -> "SurfaceForcing":
|
|
561
628
|
"""Create an instance of the SurfaceForcing class from a YAML file.
|
|
562
629
|
|
|
@@ -566,10 +633,6 @@ class SurfaceForcing:
|
|
|
566
633
|
The path to the YAML file from which the parameters will be read.
|
|
567
634
|
use_dask: bool, optional
|
|
568
635
|
Indicates whether to use dask for processing. If True, data is processed with dask; if False, data is processed eagerly. Defaults to False.
|
|
569
|
-
bypass_validation: bool, optional
|
|
570
|
-
Indicates whether to skip validation checks in the processed data. When set to True,
|
|
571
|
-
the validation process that ensures no NaN values exist at wet points
|
|
572
|
-
in the processed dataset is bypassed. Defaults to False.
|
|
573
636
|
|
|
574
637
|
Returns
|
|
575
638
|
-------
|
|
@@ -581,6 +644,4 @@ class SurfaceForcing:
|
|
|
581
644
|
grid = Grid.from_yaml(filepath)
|
|
582
645
|
params = _from_yaml(cls, filepath)
|
|
583
646
|
|
|
584
|
-
return cls(
|
|
585
|
-
grid=grid, **params, use_dask=use_dask, bypass_validation=bypass_validation
|
|
586
|
-
)
|
|
647
|
+
return cls(grid=grid, **params, use_dask=use_dask)
|
roms_tools/setup/tides.py
CHANGED
|
@@ -9,6 +9,7 @@ from dataclasses import dataclass, field
|
|
|
9
9
|
from roms_tools import Grid
|
|
10
10
|
from roms_tools.plot import _plot
|
|
11
11
|
from roms_tools.regrid import LateralRegrid
|
|
12
|
+
from roms_tools.utils import save_datasets
|
|
12
13
|
from roms_tools.setup.datasets import TPXODataset
|
|
13
14
|
from roms_tools.setup.utils import (
|
|
14
15
|
nan_check,
|
|
@@ -16,7 +17,6 @@ from roms_tools.setup.utils import (
|
|
|
16
17
|
interpolate_from_rho_to_u,
|
|
17
18
|
interpolate_from_rho_to_v,
|
|
18
19
|
get_variable_metadata,
|
|
19
|
-
save_datasets,
|
|
20
20
|
get_target_coords,
|
|
21
21
|
rotate_velocities,
|
|
22
22
|
get_vector_pairs,
|
|
@@ -84,6 +84,9 @@ class TidalForcing:
|
|
|
84
84
|
target_coords,
|
|
85
85
|
buffer_points=20,
|
|
86
86
|
)
|
|
87
|
+
# Enforce double precision to ensure reproducibility
|
|
88
|
+
data.convert_to_float64()
|
|
89
|
+
|
|
87
90
|
# select desired number of constituents
|
|
88
91
|
object.__setattr__(data, "ds", data.ds.isel(ntides=slice(None, self.ntides)))
|
|
89
92
|
self._correct_tides(data)
|
|
@@ -368,36 +371,19 @@ class TidalForcing:
|
|
|
368
371
|
kwargs=kwargs,
|
|
369
372
|
)
|
|
370
373
|
|
|
371
|
-
def save(
|
|
372
|
-
self, filepath: Union[str, Path], np_eta: int = None, np_xi: int = None
|
|
373
|
-
) -> None:
|
|
374
|
+
def save(self, filepath: Union[str, Path]) -> None:
|
|
374
375
|
"""Save the tidal forcing information to a netCDF4 file.
|
|
375
376
|
|
|
376
|
-
This method supports saving the dataset in two modes:
|
|
377
|
-
|
|
378
|
-
1. **Single File Mode (default)**:
|
|
379
|
-
|
|
380
|
-
If both `np_eta` and `np_xi` are `None`, the entire dataset is saved as a single netCDF4 file
|
|
381
|
-
with the base filename specified by `filepath.nc`.
|
|
382
|
-
|
|
383
|
-
2. **Partitioned Mode**:
|
|
384
|
-
|
|
385
|
-
- If either `np_eta` or `np_xi` is specified, the dataset is divided into spatial tiles along the eta-axis and xi-axis.
|
|
386
|
-
- Each spatial tile is saved as a separate netCDF4 file.
|
|
387
|
-
|
|
388
377
|
Parameters
|
|
389
378
|
----------
|
|
390
379
|
filepath : Union[str, Path]
|
|
391
|
-
The
|
|
392
|
-
|
|
393
|
-
The number of partitions along the `eta` direction. If `None`, no spatial partitioning is performed.
|
|
394
|
-
np_xi : int, optional
|
|
395
|
-
The number of partitions along the `xi` direction. If `None`, no spatial partitioning is performed.
|
|
380
|
+
The path or filename where the dataset will be saved. If a directory is specified,
|
|
381
|
+
the file will be saved with a default name within that directory.
|
|
396
382
|
|
|
397
383
|
Returns
|
|
398
384
|
-------
|
|
399
|
-
|
|
400
|
-
A
|
|
385
|
+
Path
|
|
386
|
+
A `Path` object representing the location of the saved file.
|
|
401
387
|
"""
|
|
402
388
|
|
|
403
389
|
# Ensure filepath is a Path object
|
|
@@ -407,17 +393,11 @@ class TidalForcing:
|
|
|
407
393
|
if filepath.suffix == ".nc":
|
|
408
394
|
filepath = filepath.with_suffix("")
|
|
409
395
|
|
|
410
|
-
if self.use_dask:
|
|
411
|
-
from dask.diagnostics import ProgressBar
|
|
412
|
-
|
|
413
|
-
with ProgressBar():
|
|
414
|
-
self.ds.load()
|
|
415
|
-
|
|
416
396
|
dataset_list = [self.ds]
|
|
417
397
|
output_filenames = [str(filepath)]
|
|
418
398
|
|
|
419
399
|
saved_filenames = save_datasets(
|
|
420
|
-
dataset_list, output_filenames,
|
|
400
|
+
dataset_list, output_filenames, use_dask=self.use_dask
|
|
421
401
|
)
|
|
422
402
|
|
|
423
403
|
return saved_filenames
|
|
@@ -439,7 +419,6 @@ class TidalForcing:
|
|
|
439
419
|
cls,
|
|
440
420
|
filepath: Union[str, Path],
|
|
441
421
|
use_dask: bool = False,
|
|
442
|
-
bypass_validation: bool = False,
|
|
443
422
|
) -> "TidalForcing":
|
|
444
423
|
"""Create an instance of the TidalForcing class from a YAML file.
|
|
445
424
|
|
|
@@ -449,10 +428,6 @@ class TidalForcing:
|
|
|
449
428
|
The path to the YAML file from which the parameters will be read.
|
|
450
429
|
use_dask: bool, optional
|
|
451
430
|
Indicates whether to use dask for processing. If True, data is processed with dask; if False, data is processed eagerly. Defaults to False.
|
|
452
|
-
bypass_validation: bool, optional
|
|
453
|
-
Indicates whether to skip validation checks in the processed data. When set to True,
|
|
454
|
-
the validation process that ensures no NaN values exist at wet points
|
|
455
|
-
in the processed dataset is bypassed. Defaults to False.
|
|
456
431
|
|
|
457
432
|
Returns
|
|
458
433
|
-------
|
|
@@ -467,7 +442,6 @@ class TidalForcing:
|
|
|
467
442
|
grid=grid,
|
|
468
443
|
**tidal_forcing_params,
|
|
469
444
|
use_dask=use_dask,
|
|
470
|
-
bypass_validation=bypass_validation,
|
|
471
445
|
)
|
|
472
446
|
|
|
473
447
|
def _correct_tides(self, data):
|
roms_tools/setup/topography.py
CHANGED
|
@@ -145,6 +145,8 @@ def _make_raw_topography(
|
|
|
145
145
|
The regridded topography data with the sign flipped (bathymetry positive).
|
|
146
146
|
"""
|
|
147
147
|
data.choose_subdomain(target_coords, buffer_points=3, verbose=verbose)
|
|
148
|
+
# Enforce double precision to ensure reproducibility
|
|
149
|
+
data.convert_to_float64()
|
|
148
150
|
|
|
149
151
|
if verbose:
|
|
150
152
|
start_time = time.time()
|
|
@@ -233,7 +235,7 @@ def _smooth_topography_locally(h, hmin=5, rmax=0.2):
|
|
|
233
235
|
rmax_log = 0.0
|
|
234
236
|
|
|
235
237
|
# Apply hmin threshold
|
|
236
|
-
h =
|
|
238
|
+
h = _clip_depth(h, hmin)
|
|
237
239
|
|
|
238
240
|
# Perform logarithmic transformation of the height field
|
|
239
241
|
h_log = np.log(h / hmin)
|
|
@@ -316,7 +318,7 @@ def _smooth_topography_locally(h, hmin=5, rmax=0.2):
|
|
|
316
318
|
h = hmin * np.exp(h_log)
|
|
317
319
|
|
|
318
320
|
# Apply hmin threshold again
|
|
319
|
-
h =
|
|
321
|
+
h = _clip_depth(h, hmin)
|
|
320
322
|
|
|
321
323
|
# Compute maximum slope parameter r
|
|
322
324
|
r_eta, r_xi = _compute_rfactor(h)
|
|
@@ -327,6 +329,27 @@ def _smooth_topography_locally(h, hmin=5, rmax=0.2):
|
|
|
327
329
|
return h
|
|
328
330
|
|
|
329
331
|
|
|
332
|
+
def _clip_depth(h: xr.DataArray, hmin: float) -> xr.DataArray:
|
|
333
|
+
"""Ensures that depth values do not fall below a minimum threshold.
|
|
334
|
+
|
|
335
|
+
This function replaces all depth values in `h` that are less than `hmin` with `hmin`,
|
|
336
|
+
ensuring a minimum depth constraint.
|
|
337
|
+
|
|
338
|
+
Parameters
|
|
339
|
+
----------
|
|
340
|
+
h : xr.DataArray
|
|
341
|
+
The depth (bathymetry) array.
|
|
342
|
+
hmin : float
|
|
343
|
+
The minimum allowable depth value.
|
|
344
|
+
|
|
345
|
+
Returns
|
|
346
|
+
-------
|
|
347
|
+
xr.DataArray
|
|
348
|
+
The modified depth array with values clipped at `hmin`.
|
|
349
|
+
"""
|
|
350
|
+
return xr.where(h < hmin, hmin, h)
|
|
351
|
+
|
|
352
|
+
|
|
330
353
|
def _compute_rfactor(h):
|
|
331
354
|
"""Computes the slope parameter (r-factor) in both horizontal directions.
|
|
332
355
|
|