roms-tools 3.3.0__py3-none-any.whl → 3.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- roms_tools/__init__.py +1 -1
- roms_tools/analysis/cdr_ensemble.py +10 -13
- roms_tools/analysis/roms_output.py +5 -304
- roms_tools/{download.py → datasets/download.py} +1 -0
- roms_tools/{setup → datasets}/lat_lon_datasets.py +88 -64
- roms_tools/{setup → datasets}/river_datasets.py +9 -4
- roms_tools/datasets/roms_dataset.py +854 -0
- roms_tools/datasets/utils.py +487 -0
- roms_tools/{setup/fill.py → fill.py} +110 -13
- roms_tools/plot.py +4 -4
- roms_tools/regrid.py +76 -0
- roms_tools/setup/boundary_forcing.py +53 -45
- roms_tools/setup/cdr_release.py +2 -4
- roms_tools/setup/grid.py +46 -15
- roms_tools/setup/initial_conditions.py +330 -71
- roms_tools/setup/mask.py +2 -5
- roms_tools/setup/nesting.py +13 -6
- roms_tools/setup/river_forcing.py +4 -4
- roms_tools/setup/surface_forcing.py +15 -11
- roms_tools/setup/tides.py +7 -6
- roms_tools/setup/topography.py +10 -2
- roms_tools/setup/utils.py +292 -666
- roms_tools/tests/test_analysis/test_cdr_ensemble.py +4 -6
- roms_tools/tests/test_analysis/test_roms_output.py +1 -220
- roms_tools/tests/{test_setup → test_datasets}/test_lat_lon_datasets.py +4 -4
- roms_tools/tests/{test_setup → test_datasets}/test_river_datasets.py +1 -1
- roms_tools/tests/test_datasets/test_roms_dataset.py +743 -0
- roms_tools/tests/test_datasets/test_utils.py +527 -0
- roms_tools/tests/{test_setup/test_fill.py → test_fill.py} +72 -9
- roms_tools/tests/test_regrid.py +120 -1
- roms_tools/tests/test_setup/test_boundary_forcing.py +57 -138
- roms_tools/tests/test_setup/test_cdr_release.py +4 -5
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zarr.json +293 -2021
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zarr.json +294 -2022
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ALK/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/ALK_west → initial_conditions_from_roms.zarr/ALK}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ALK_ALT_CO2/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west → initial_conditions_from_roms.zarr/ALK_ALT_CO2}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Cs_r/c/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west → initial_conditions_from_roms.zarr/Cs_r}/zarr.json +5 -12
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Cs_w/c/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatFe_west → initial_conditions_from_roms.zarr/Cs_w}/zarr.json +3 -10
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOCr_west → initial_conditions_from_roms.zarr/DIC}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC_ALT_CO2/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DIC_ALT_CO2/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOC/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOCr/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west → initial_conditions_from_roms.zarr/DOCr}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DON/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DON/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DONr/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DONr/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOP/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOP/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOPr/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/DOPr/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Fe/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Fe/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/Lig/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOP_west → initial_conditions_from_roms.zarr/Lig}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NH4/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DON_west → initial_conditions_from_roms.zarr/NH4}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NO3/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/NO3/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/O2/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/Lig_west → initial_conditions_from_roms.zarr/O2}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/PO4/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/PO4/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/SiO3/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/SiO3/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/abs_time/zarr.json +47 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatC_west → initial_conditions_from_roms.zarr/diatC}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatChl/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diatChl_west → initial_conditions_from_roms.zarr/diatChl}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatFe/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/O2_west → initial_conditions_from_roms.zarr/diatFe}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatP/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DIC_west → initial_conditions_from_roms.zarr/diatP}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diatSi/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/DOC_west → initial_conditions_from_roms.zarr/diatSi}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazC/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazChl/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/diazChl_west → initial_conditions_from_roms.zarr/diazChl}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazFe/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/Fe_west → initial_conditions_from_roms.zarr/diazFe}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazP/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/diazP/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ocean_time/c/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ocean_time/zarr.json +47 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/salt/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west → initial_conditions_from_roms.zarr/salt}/zarr.json +12 -9
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spC/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spCaCO3/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spCaCO3/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spChl/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/spChl_west → initial_conditions_from_roms.zarr/spChl}/zarr.json +11 -8
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spFe/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spFe/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spP/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/spP/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/temp/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/temp/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/u/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/{bgc_boundary_forcing_from_climatology.zarr/NH4_west → initial_conditions_from_roms.zarr/u}/zarr.json +12 -9
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ubar/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/ubar/zarr.json +54 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/v/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/v/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/vbar/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/vbar/zarr.json +54 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/w/zarr.json +57 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zarr.json +2481 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zeta/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zeta/zarr.json +54 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zooC/c/0/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/initial_conditions_from_roms.zarr/zooC/zarr.json +57 -0
- roms_tools/tests/test_setup/test_grid.py +66 -1
- roms_tools/tests/test_setup/test_initial_conditions.py +130 -104
- roms_tools/tests/test_setup/test_nesting.py +2 -1
- roms_tools/tests/test_setup/test_surface_forcing.py +1 -1
- roms_tools/tests/test_setup/test_tides.py +1 -1
- roms_tools/tests/test_setup/test_utils.py +100 -15
- roms_tools/tests/test_setup/test_validation.py +15 -0
- roms_tools/tests/test_tiling/test_partition.py +63 -15
- roms_tools/tests/test_utils.py +365 -0
- roms_tools/tiling/partition.py +81 -211
- roms_tools/utils.py +360 -62
- {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/METADATA +2 -3
- {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/RECORD +137 -174
- {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/WHEEL +1 -1
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/ALK_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DIC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DON_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DONr_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/DOPr_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Fe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/Lig_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NH4_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/NO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/O2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/PO4_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/SiO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diatSi_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazFe_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/diazP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spCaCO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spFe_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/spP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_climatology.zarr/zooC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_ALT_CO2_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/ALK_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_ALT_CO2_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DIC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOCr_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DON_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DONr_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/DOPr_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Fe_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/Lig_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NH4_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/NO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/O2_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/PO4_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/SiO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatChl_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diatSi_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazChl_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazFe_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/diazP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spC_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spCaCO3_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spChl_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spFe_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/spP_west/zarr.json +0 -54
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/c/0/0/0 +0 -0
- roms_tools/tests/test_setup/test_data/bgc_boundary_forcing_from_unified_climatology.zarr/zooC_west/zarr.json +0 -54
- {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/licenses/LICENSE +0 -0
- {roms_tools-3.3.0.dist-info → roms_tools-3.5.0.dist-info}/top_level.txt +0 -0
roms_tools/tests/test_utils.py
CHANGED
|
@@ -3,17 +3,29 @@ from pathlib import Path
|
|
|
3
3
|
from unittest import mock
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
6
7
|
import pytest
|
|
7
8
|
import xarray as xr
|
|
8
9
|
|
|
10
|
+
from roms_tools.datasets.download import download_test_data
|
|
11
|
+
from roms_tools.datasets.lat_lon_datasets import ERA5Correction
|
|
9
12
|
from roms_tools.utils import (
|
|
13
|
+
_interpolate_generic,
|
|
10
14
|
_path_list_from_input,
|
|
11
15
|
generate_focused_coordinate_range,
|
|
12
16
|
get_dask_chunks,
|
|
13
17
|
has_copernicus,
|
|
14
18
|
has_dask,
|
|
15
19
|
has_gcsfs,
|
|
20
|
+
interpolate_cyclic_time,
|
|
21
|
+
interpolate_from_climatology,
|
|
22
|
+
interpolate_from_rho_to_u,
|
|
23
|
+
interpolate_from_rho_to_v,
|
|
24
|
+
interpolate_from_u_to_rho,
|
|
25
|
+
interpolate_from_v_to_rho,
|
|
16
26
|
load_data,
|
|
27
|
+
rotate_velocities,
|
|
28
|
+
wrap_longitudes,
|
|
17
29
|
)
|
|
18
30
|
|
|
19
31
|
|
|
@@ -241,3 +253,356 @@ def test_time_chunking_false_roms():
|
|
|
241
253
|
dim_names = {"time": "ocean_time"}
|
|
242
254
|
result = get_dask_chunks(dim_names, time_chunking=False)
|
|
243
255
|
assert "ocean_time" not in result
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
# test interpolate_from_climatology
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
@pytest.fixture
|
|
262
|
+
def climatology_data():
|
|
263
|
+
"""Create a simple annual cycle dataset with 12 time points."""
|
|
264
|
+
time_coord = np.arange(1, 13) # months as day_of_year approximation
|
|
265
|
+
da = xr.DataArray(np.arange(12), dims=("time",), coords={"time": time_coord})
|
|
266
|
+
ds = xr.Dataset({"var1": da, "var2": da * 2})
|
|
267
|
+
return da, ds, "time", "time"
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def test_interpolate_dataarray_single_time(climatology_data):
|
|
271
|
+
da, _, time_dim, time_coord = climatology_data
|
|
272
|
+
target_time = pd.Timestamp("2000-03-15") # day_of_year ~ 75
|
|
273
|
+
interpolated = interpolate_from_climatology(da, time_dim, time_coord, target_time)
|
|
274
|
+
assert isinstance(interpolated, xr.DataArray)
|
|
275
|
+
assert interpolated.sizes[time_dim] == 1
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def test_interpolate_dataset_multiple_times(climatology_data):
|
|
279
|
+
_, ds, time_dim, time_coord = climatology_data
|
|
280
|
+
target_times = pd.date_range("2000-01-01", periods=3, freq="ME")
|
|
281
|
+
interpolated = interpolate_from_climatology(ds, time_dim, time_coord, target_times)
|
|
282
|
+
assert isinstance(interpolated, xr.Dataset)
|
|
283
|
+
assert all(interpolated[var].sizes[time_dim] == 3 for var in interpolated.data_vars)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def test_interpolate_dataarray_time_dim_not_equal_time_coord():
|
|
287
|
+
time_values = np.arange(1, 13)
|
|
288
|
+
da = xr.DataArray(
|
|
289
|
+
np.arange(12),
|
|
290
|
+
dims=("time_dim",),
|
|
291
|
+
coords={"time_coord": ("time_dim", time_values)},
|
|
292
|
+
)
|
|
293
|
+
target_time = pd.Timestamp("2000-06-15")
|
|
294
|
+
interpolated = interpolate_from_climatology(
|
|
295
|
+
da, time_dim="time_dim", time_coord="time_coord", time=target_time
|
|
296
|
+
)
|
|
297
|
+
assert interpolated.sizes["time_dim"] == 1
|
|
298
|
+
assert np.issubdtype(interpolated.dtype, np.number)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def test_interpolate_cyclic_time_basic():
|
|
302
|
+
time_values = np.arange(1, 13)
|
|
303
|
+
da = xr.DataArray(np.arange(12), dims=("time",), coords={"time": time_values})
|
|
304
|
+
target_days = [0.5, 6.5, 12.5] # fractional days, include cyclic behavior
|
|
305
|
+
interpolated = interpolate_cyclic_time(
|
|
306
|
+
da, time_dim="time", time_coord="time", day_of_year=target_days
|
|
307
|
+
)
|
|
308
|
+
assert isinstance(interpolated, xr.DataArray)
|
|
309
|
+
assert interpolated.sizes["time"] == len(target_days)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_interpolate_from_climatology_invalid_input():
|
|
313
|
+
with pytest.raises(TypeError):
|
|
314
|
+
interpolate_from_climatology(
|
|
315
|
+
"not a dataset", "time", "time", pd.Timestamp("2000-01-01")
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def test_interpolate_from_real_climatology(use_dask):
|
|
320
|
+
fname = download_test_data("ERA5_regional_test_data.nc")
|
|
321
|
+
era5_times = xr.open_dataset(fname).time
|
|
322
|
+
|
|
323
|
+
climatology = ERA5Correction(use_dask=use_dask)
|
|
324
|
+
field = climatology.ds["ssr_corr"]
|
|
325
|
+
field["time"] = field["time"].dt.days
|
|
326
|
+
|
|
327
|
+
interpolated_field = interpolate_from_climatology(field, "time", "time", era5_times)
|
|
328
|
+
assert len(interpolated_field.time) == len(era5_times)
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def test_wrap_longitudes_staggered():
|
|
332
|
+
# Dimensions
|
|
333
|
+
eta_rho, xi_rho, xi_u = 3, 4, 5
|
|
334
|
+
eta_v = 2
|
|
335
|
+
|
|
336
|
+
# Create 2D coordinates
|
|
337
|
+
lon_rho = xr.DataArray(
|
|
338
|
+
np.linspace(0, 360, eta_rho * xi_rho).reshape(eta_rho, xi_rho),
|
|
339
|
+
dims=("eta_rho", "xi_rho"),
|
|
340
|
+
attrs={"units": "degrees_east"},
|
|
341
|
+
)
|
|
342
|
+
lon_u = xr.DataArray(
|
|
343
|
+
np.linspace(-190, 190, eta_rho * xi_u).reshape(eta_rho, xi_u),
|
|
344
|
+
dims=("eta_rho", "xi_u"),
|
|
345
|
+
attrs={"units": "degrees_east"},
|
|
346
|
+
)
|
|
347
|
+
lon_v = xr.DataArray(
|
|
348
|
+
np.linspace(-180, 180, eta_v * xi_rho).reshape(eta_v, xi_rho),
|
|
349
|
+
dims=("eta_v", "xi_rho"),
|
|
350
|
+
attrs={"units": "degrees_east"},
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
# Dummy variables
|
|
354
|
+
ds = xr.Dataset(
|
|
355
|
+
{
|
|
356
|
+
"dummy_rho": (("eta_rho", "xi_rho"), np.zeros((eta_rho, xi_rho))),
|
|
357
|
+
"dummy_u": (("eta_rho", "xi_u"), np.zeros((eta_rho, xi_u))),
|
|
358
|
+
"dummy_v": (("eta_v", "xi_rho"), np.zeros((eta_v, xi_rho))),
|
|
359
|
+
},
|
|
360
|
+
coords={"lon_rho": lon_rho, "lon_u": lon_u, "lon_v": lon_v},
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Wrap to [-180, 180]
|
|
364
|
+
ds_wrapped = wrap_longitudes(ds, straddle=True)
|
|
365
|
+
|
|
366
|
+
# Check values: all >180 should be shifted
|
|
367
|
+
assert ds_wrapped.lon_rho.max().values <= 180
|
|
368
|
+
assert ds_wrapped.lon_u.max().values <= 180
|
|
369
|
+
assert ds_wrapped.lon_v.max().values <= 180
|
|
370
|
+
|
|
371
|
+
# Wrap to [0, 360]
|
|
372
|
+
ds_wrapped2 = wrap_longitudes(ds, straddle=False)
|
|
373
|
+
assert ds_wrapped2.lon_rho.min().values >= 0
|
|
374
|
+
assert ds_wrapped2.lon_u.min().values >= 0
|
|
375
|
+
assert ds_wrapped2.lon_v.min().values >= 0
|
|
376
|
+
|
|
377
|
+
# Check attributes preserved
|
|
378
|
+
for name in ["lon_rho", "lon_u", "lon_v"]:
|
|
379
|
+
assert ds.coords[name].attrs == ds_wrapped.coords[name].attrs
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
# test _interpolate_generic and its wrappers
|
|
383
|
+
|
|
384
|
+
# -------------------------
|
|
385
|
+
# Fixtures
|
|
386
|
+
# -------------------------
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@pytest.fixture
|
|
390
|
+
def sample_rho_field() -> xr.DataArray:
|
|
391
|
+
"""Create a simple rho-point field for testing."""
|
|
392
|
+
data = np.arange(12, dtype=float).reshape(3, 4)
|
|
393
|
+
eta = np.arange(3)
|
|
394
|
+
xi = np.arange(4)
|
|
395
|
+
|
|
396
|
+
return xr.DataArray(
|
|
397
|
+
data,
|
|
398
|
+
dims=("eta_rho", "xi_rho"),
|
|
399
|
+
coords={
|
|
400
|
+
"lat_rho": (("eta_rho", "xi_rho"), eta[:, None] * np.ones((1, 4))),
|
|
401
|
+
"lon_rho": (("eta_rho", "xi_rho"), np.ones((3, 1)) * xi[None, :]),
|
|
402
|
+
},
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
@pytest.fixture
|
|
407
|
+
def sample_u_field() -> xr.DataArray:
|
|
408
|
+
"""Create a simple u-point field for testing."""
|
|
409
|
+
data = np.arange(9, dtype=float).reshape(3, 3)
|
|
410
|
+
eta = np.arange(3)
|
|
411
|
+
xi = np.arange(3)
|
|
412
|
+
|
|
413
|
+
return xr.DataArray(
|
|
414
|
+
data,
|
|
415
|
+
dims=("eta_rho", "xi_u"),
|
|
416
|
+
coords={
|
|
417
|
+
"lat_u": (("eta_rho", "xi_u"), eta[:, None] * np.ones((1, 3))),
|
|
418
|
+
"lon_u": (("eta_rho", "xi_u"), np.ones((3, 1)) * xi[None, :]),
|
|
419
|
+
},
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
@pytest.fixture
|
|
424
|
+
def sample_v_field() -> xr.DataArray:
|
|
425
|
+
"""Create a simple v-point field for testing."""
|
|
426
|
+
data = np.arange(8, dtype=float).reshape(2, 4)
|
|
427
|
+
eta = np.arange(2)
|
|
428
|
+
xi = np.arange(4)
|
|
429
|
+
|
|
430
|
+
return xr.DataArray(
|
|
431
|
+
data,
|
|
432
|
+
dims=("eta_v", "xi_rho"),
|
|
433
|
+
coords={
|
|
434
|
+
"lat_v": (("eta_v", "xi_rho"), eta[:, None] * np.ones((1, 4))),
|
|
435
|
+
"lon_v": (("eta_v", "xi_rho"), np.ones((2, 1)) * xi[None, :]),
|
|
436
|
+
},
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
# -------------------------
|
|
441
|
+
# Generic interpolation tests
|
|
442
|
+
# -------------------------
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def test_interpolate_from_rho_to_u_additive(sample_rho_field: xr.DataArray):
|
|
446
|
+
result = _interpolate_generic(
|
|
447
|
+
sample_rho_field, dim_in="xi_rho", dim_out="xi_u", method="additive"
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
# One fewer point along xi
|
|
451
|
+
assert result.shape[1] == sample_rho_field.shape[1] - 1
|
|
452
|
+
|
|
453
|
+
expected = 0.5 * (sample_rho_field.values[:, 1:] + sample_rho_field.values[:, :-1])
|
|
454
|
+
np.testing.assert_allclose(result.values, expected)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def test_interpolate_from_rho_to_u_multiplicative(sample_rho_field: xr.DataArray):
|
|
458
|
+
result = _interpolate_generic(
|
|
459
|
+
sample_rho_field, dim_in="xi_rho", dim_out="xi_u", method="multiplicative"
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
expected = sample_rho_field.values[:, 1:] * sample_rho_field.values[:, :-1]
|
|
463
|
+
np.testing.assert_allclose(result.values, expected)
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
# -------------------------
|
|
467
|
+
# Wrapper tests
|
|
468
|
+
# -------------------------
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def test_rho_to_u_wrapper_additive(sample_rho_field: xr.DataArray):
|
|
472
|
+
result = interpolate_from_rho_to_u(sample_rho_field, method="additive")
|
|
473
|
+
|
|
474
|
+
# Dimension swap
|
|
475
|
+
assert "xi_u" in result.dims
|
|
476
|
+
assert "xi_rho" not in result.dims
|
|
477
|
+
|
|
478
|
+
# Coordinates dropped
|
|
479
|
+
for coord in ("lat_rho", "lon_rho"):
|
|
480
|
+
assert coord not in result.coords
|
|
481
|
+
|
|
482
|
+
# Shape check
|
|
483
|
+
assert result.sizes["xi_u"] == sample_rho_field.sizes["xi_rho"] - 1
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def test_rho_to_v_wrapper_additive(sample_rho_field: xr.DataArray):
|
|
487
|
+
result = interpolate_from_rho_to_v(sample_rho_field, method="additive")
|
|
488
|
+
|
|
489
|
+
# Dimension swap
|
|
490
|
+
assert "eta_v" in result.dims
|
|
491
|
+
assert "eta_rho" not in result.dims
|
|
492
|
+
|
|
493
|
+
# Coordinates dropped
|
|
494
|
+
for coord in ("lat_rho", "lon_rho"):
|
|
495
|
+
assert coord not in result.coords
|
|
496
|
+
|
|
497
|
+
# Shape check
|
|
498
|
+
assert result.sizes["eta_v"] == sample_rho_field.sizes["eta_rho"] - 1
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
def test_u_to_rho_wrapper_additive(sample_u_field: xr.DataArray):
|
|
502
|
+
result = interpolate_from_u_to_rho(sample_u_field, method="additive")
|
|
503
|
+
|
|
504
|
+
# Dimension swap
|
|
505
|
+
assert "xi_rho" in result.dims
|
|
506
|
+
assert "xi_u" not in result.dims
|
|
507
|
+
|
|
508
|
+
# Coordinates dropped
|
|
509
|
+
for coord in ("lat_u", "lon_u"):
|
|
510
|
+
assert coord not in result.coords
|
|
511
|
+
|
|
512
|
+
# Shape: one more along xi due to padding
|
|
513
|
+
assert result.sizes["xi_rho"] == sample_u_field.sizes["xi_u"] + 1
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def test_v_to_rho_wrapper_additive(sample_v_field: xr.DataArray):
|
|
517
|
+
result = interpolate_from_v_to_rho(sample_v_field, method="additive")
|
|
518
|
+
|
|
519
|
+
# Dimension swap
|
|
520
|
+
assert "eta_rho" in result.dims
|
|
521
|
+
assert "eta_v" not in result.dims
|
|
522
|
+
|
|
523
|
+
# Coordinates dropped
|
|
524
|
+
for coord in ("lat_v", "lon_v"):
|
|
525
|
+
assert coord not in result.coords
|
|
526
|
+
|
|
527
|
+
# Shape: one more along eta due to padding
|
|
528
|
+
assert result.sizes["eta_rho"] == sample_v_field.sizes["eta_v"] + 1
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
# -------------------------
|
|
532
|
+
# Error handling
|
|
533
|
+
# -------------------------
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def test_invalid_method_raises(
|
|
537
|
+
sample_rho_field: xr.DataArray,
|
|
538
|
+
sample_u_field: xr.DataArray,
|
|
539
|
+
sample_v_field: xr.DataArray,
|
|
540
|
+
):
|
|
541
|
+
with pytest.raises(NotImplementedError):
|
|
542
|
+
interpolate_from_rho_to_u(sample_rho_field, method="unsupported")
|
|
543
|
+
|
|
544
|
+
with pytest.raises(NotImplementedError):
|
|
545
|
+
interpolate_from_rho_to_v(sample_rho_field, method="unsupported")
|
|
546
|
+
|
|
547
|
+
with pytest.raises(NotImplementedError):
|
|
548
|
+
interpolate_from_u_to_rho(sample_u_field, method="unsupported")
|
|
549
|
+
|
|
550
|
+
with pytest.raises(NotImplementedError):
|
|
551
|
+
interpolate_from_v_to_rho(sample_v_field, method="unsupported")
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
# Test rotate_velocities
|
|
555
|
+
@pytest.fixture
|
|
556
|
+
def sample_velocities_centered():
|
|
557
|
+
"""Create a centered-grid velocity field with random values and grid angle."""
|
|
558
|
+
np.random.seed(42) # For reproducibility
|
|
559
|
+
|
|
560
|
+
eta_rho, xi_rho = 10, 15
|
|
561
|
+
|
|
562
|
+
u = xr.DataArray(
|
|
563
|
+
np.random.rand(eta_rho, xi_rho),
|
|
564
|
+
dims=("eta_rho", "xi_rho"),
|
|
565
|
+
coords={
|
|
566
|
+
"eta_rho": np.arange(eta_rho),
|
|
567
|
+
"xi_rho": np.arange(xi_rho),
|
|
568
|
+
},
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
v = xr.DataArray(
|
|
572
|
+
np.random.rand(eta_rho, xi_rho),
|
|
573
|
+
dims=("eta_rho", "xi_rho"),
|
|
574
|
+
coords={
|
|
575
|
+
"eta_rho": np.arange(eta_rho),
|
|
576
|
+
"xi_rho": np.arange(xi_rho),
|
|
577
|
+
},
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
angle = xr.DataArray(
|
|
581
|
+
np.random.rand(eta_rho, xi_rho) * np.pi / 2
|
|
582
|
+
- np.pi / 4, # random angles in [-45°, 45°]
|
|
583
|
+
dims=("eta_rho", "xi_rho"),
|
|
584
|
+
coords={
|
|
585
|
+
"eta_rho": np.arange(eta_rho),
|
|
586
|
+
"xi_rho": np.arange(xi_rho),
|
|
587
|
+
},
|
|
588
|
+
)
|
|
589
|
+
|
|
590
|
+
return u, v, angle
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
def test_rotate_velocities_roundtrip(sample_velocities_centered):
|
|
594
|
+
"""Test rotation to grid and back recovers original velocities."""
|
|
595
|
+
u, v, angle = sample_velocities_centered
|
|
596
|
+
|
|
597
|
+
# Rotate forward: lat-lon → model grid
|
|
598
|
+
u_rot, v_rot = rotate_velocities(
|
|
599
|
+
u, v, angle, interpolate_before=False, interpolate_after=False
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
# Rotate backward: model grid → lat-lon
|
|
603
|
+
u_back, v_back = rotate_velocities(
|
|
604
|
+
u_rot, v_rot, -angle, interpolate_before=False, interpolate_after=False
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
np.testing.assert_allclose(u.values, u_back.values)
|
|
608
|
+
np.testing.assert_allclose(v.values, v_back.values)
|