roms-tools 2.2.1__py3-none-any.whl → 2.4.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 -0
- roms_tools/analysis/roms_output.py +590 -0
- roms_tools/{setup/download.py → download.py} +3 -0
- roms_tools/{setup/plot.py → plot.py} +34 -28
- roms_tools/setup/boundary_forcing.py +199 -203
- roms_tools/setup/datasets.py +60 -136
- roms_tools/setup/grid.py +40 -67
- roms_tools/setup/initial_conditions.py +249 -247
- roms_tools/setup/nesting.py +6 -27
- roms_tools/setup/river_forcing.py +41 -76
- roms_tools/setup/surface_forcing.py +125 -75
- roms_tools/setup/tides.py +31 -51
- roms_tools/setup/topography.py +1 -1
- roms_tools/setup/utils.py +44 -224
- roms_tools/tests/test_analysis/test_roms_output.py +269 -0
- roms_tools/tests/{test_setup/test_regrid.py → test_regrid.py} +1 -1
- roms_tools/tests/test_setup/test_boundary_forcing.py +221 -58
- 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_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/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/river_forcing_no_climatology.zarr/.zmetadata +30 -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 +30 -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_datasets.py +1 -1
- roms_tools/tests/test_setup/test_grid.py +1 -14
- roms_tools/tests/test_setup/test_initial_conditions.py +205 -67
- roms_tools/tests/test_setup/test_nesting.py +0 -16
- roms_tools/tests/test_setup/test_river_forcing.py +9 -37
- roms_tools/tests/test_setup/test_surface_forcing.py +103 -74
- roms_tools/tests/test_setup/test_tides.py +5 -17
- roms_tools/tests/test_setup/test_topography.py +1 -1
- roms_tools/tests/test_setup/test_utils.py +57 -1
- roms_tools/tests/{test_utils.py → test_tiling/test_partition.py} +1 -1
- roms_tools/tiling/partition.py +338 -0
- roms_tools/utils.py +310 -276
- roms_tools/vertical_coordinate.py +227 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/METADATA +1 -1
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/RECORD +151 -142
- roms_tools/setup/vertical_coordinate.py +0 -109
- /roms_tools/{setup/regrid.py → regrid.py} +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/LICENSE +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/WHEEL +0 -0
- {roms_tools-2.2.1.dist-info → roms_tools-2.4.0.dist-info}/top_level.txt +0 -0
|
@@ -2,10 +2,11 @@ import pytest
|
|
|
2
2
|
from datetime import datetime
|
|
3
3
|
import xarray as xr
|
|
4
4
|
from roms_tools import Grid, SurfaceForcing
|
|
5
|
-
from roms_tools.
|
|
5
|
+
from roms_tools.download import download_test_data
|
|
6
6
|
import textwrap
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
|
|
8
|
+
import logging
|
|
9
|
+
from conftest import calculate_data_hash
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@pytest.fixture
|
|
@@ -163,7 +164,9 @@ def grid_that_lies_west_of_dateline_more_than_five_degrees_away():
|
|
|
163
164
|
"grid_that_lies_west_of_dateline_more_than_five_degrees_away",
|
|
164
165
|
],
|
|
165
166
|
)
|
|
166
|
-
def test_successful_initialization_with_regional_data(
|
|
167
|
+
def test_successful_initialization_with_regional_data(
|
|
168
|
+
grid_fixture, request, caplog, use_dask
|
|
169
|
+
):
|
|
167
170
|
"""Test the initialization of SurfaceForcing with regional ERA5 data.
|
|
168
171
|
|
|
169
172
|
The test is performed twice:
|
|
@@ -178,16 +181,17 @@ def test_successful_initialization_with_regional_data(grid_fixture, request, use
|
|
|
178
181
|
|
|
179
182
|
grid = request.getfixturevalue(grid_fixture)
|
|
180
183
|
|
|
181
|
-
for
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
for coarse_grid_mode in ["always", "never"]:
|
|
185
|
+
with caplog.at_level(logging.INFO):
|
|
186
|
+
sfc_forcing = SurfaceForcing(
|
|
187
|
+
grid=grid,
|
|
188
|
+
start_time=start_time,
|
|
189
|
+
end_time=end_time,
|
|
190
|
+
source={"name": "ERA5", "path": fname},
|
|
191
|
+
correct_radiation=True,
|
|
192
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
193
|
+
use_dask=use_dask,
|
|
194
|
+
)
|
|
191
195
|
|
|
192
196
|
assert sfc_forcing.ds is not None
|
|
193
197
|
assert "uwnd" in sfc_forcing.ds
|
|
@@ -208,10 +212,15 @@ def test_successful_initialization_with_regional_data(grid_fixture, request, use
|
|
|
208
212
|
}
|
|
209
213
|
assert sfc_forcing.ds.coords["time"].attrs["units"] == "days"
|
|
210
214
|
|
|
211
|
-
if
|
|
215
|
+
if coarse_grid_mode == "always":
|
|
212
216
|
assert sfc_forcing.use_coarse_grid
|
|
213
|
-
|
|
217
|
+
assert (
|
|
218
|
+
"Data will be interpolated onto grid coarsened by factor 2."
|
|
219
|
+
in caplog.text
|
|
220
|
+
)
|
|
221
|
+
elif coarse_grid_mode == "never":
|
|
214
222
|
assert not sfc_forcing.use_coarse_grid
|
|
223
|
+
assert "Data will be interpolated onto fine grid." in caplog.text
|
|
215
224
|
|
|
216
225
|
sfc_forcing.plot("uwnd", time=0)
|
|
217
226
|
sfc_forcing.plot("vwnd", time=0)
|
|
@@ -239,12 +248,12 @@ def test_nan_detection_initialization_with_regional_data(
|
|
|
239
248
|
|
|
240
249
|
grid = request.getfixturevalue(grid_fixture)
|
|
241
250
|
|
|
242
|
-
for
|
|
251
|
+
for coarse_grid_mode in ["always", "never"]:
|
|
243
252
|
with pytest.raises(ValueError, match="NaN values found"):
|
|
244
253
|
|
|
245
254
|
SurfaceForcing(
|
|
246
255
|
grid=grid,
|
|
247
|
-
|
|
256
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
248
257
|
start_time=start_time,
|
|
249
258
|
end_time=end_time,
|
|
250
259
|
source={"name": "ERA5", "path": fname},
|
|
@@ -266,14 +275,14 @@ def test_no_longitude_intersection_initialization_with_regional_data(
|
|
|
266
275
|
|
|
267
276
|
fname = Path(download_test_data("ERA5_regional_test_data.nc"))
|
|
268
277
|
|
|
269
|
-
for
|
|
278
|
+
for coarse_grid_mode in ["always", "never"]:
|
|
270
279
|
with pytest.raises(
|
|
271
280
|
ValueError, match="Selected longitude range does not intersect with dataset"
|
|
272
281
|
):
|
|
273
282
|
|
|
274
283
|
SurfaceForcing(
|
|
275
284
|
grid=grid_that_straddles_180_degree_meridian,
|
|
276
|
-
|
|
285
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
277
286
|
start_time=start_time,
|
|
278
287
|
end_time=end_time,
|
|
279
288
|
source={"name": "ERA5", "path": fname},
|
|
@@ -308,10 +317,10 @@ def test_successful_initialization_with_global_data(grid_fixture, request, use_d
|
|
|
308
317
|
|
|
309
318
|
grid = request.getfixturevalue(grid_fixture)
|
|
310
319
|
|
|
311
|
-
for
|
|
320
|
+
for coarse_grid_mode in ["always", "never"]:
|
|
312
321
|
sfc_forcing = SurfaceForcing(
|
|
313
322
|
grid=grid,
|
|
314
|
-
|
|
323
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
315
324
|
start_time=start_time,
|
|
316
325
|
end_time=end_time,
|
|
317
326
|
source={"name": "ERA5", "path": fname},
|
|
@@ -336,9 +345,9 @@ def test_successful_initialization_with_global_data(grid_fixture, request, use_d
|
|
|
336
345
|
assert sfc_forcing.ds.attrs["source"] == "ERA5"
|
|
337
346
|
assert sfc_forcing.ds.coords["time"].attrs["units"] == "days"
|
|
338
347
|
|
|
339
|
-
if
|
|
348
|
+
if coarse_grid_mode == "always":
|
|
340
349
|
assert sfc_forcing.use_coarse_grid
|
|
341
|
-
|
|
350
|
+
elif coarse_grid_mode == "never":
|
|
342
351
|
assert not sfc_forcing.use_coarse_grid
|
|
343
352
|
|
|
344
353
|
|
|
@@ -356,10 +365,10 @@ def test_nans_filled_in(grid_that_straddles_dateline, use_dask):
|
|
|
356
365
|
fname = Path(download_test_data("ERA5_regional_test_data.nc"))
|
|
357
366
|
fname_bgc = Path(download_test_data("CESM_surface_global_test_data_climatology.nc"))
|
|
358
367
|
|
|
359
|
-
for
|
|
368
|
+
for coarse_grid_mode in ["always", "never"]:
|
|
360
369
|
sfc_forcing = SurfaceForcing(
|
|
361
370
|
grid=grid_that_straddles_dateline,
|
|
362
|
-
|
|
371
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
363
372
|
start_time=start_time,
|
|
364
373
|
end_time=end_time,
|
|
365
374
|
source={"name": "ERA5", "path": fname},
|
|
@@ -375,7 +384,7 @@ def test_nans_filled_in(grid_that_straddles_dateline, use_dask):
|
|
|
375
384
|
|
|
376
385
|
sfc_forcing = SurfaceForcing(
|
|
377
386
|
grid=grid_that_straddles_dateline,
|
|
378
|
-
|
|
387
|
+
coarse_grid_mode=coarse_grid_mode,
|
|
379
388
|
start_time=start_time,
|
|
380
389
|
end_time=end_time,
|
|
381
390
|
source={"name": "CESM_REGRIDDED", "path": fname_bgc, "climatology": True},
|
|
@@ -479,6 +488,57 @@ def test_surface_forcing_pco2_replication(sfc_forcing_fixture, request):
|
|
|
479
488
|
)
|
|
480
489
|
|
|
481
490
|
|
|
491
|
+
def test_determine_usage_coarse_grid():
|
|
492
|
+
# ERA5 data with 1/4 degree resolution spanning [-50E, 30E] and [40N, 80N]
|
|
493
|
+
fname = download_test_data("ERA5_regional_test_data.nc")
|
|
494
|
+
|
|
495
|
+
# at 50N, 1/4 degree of longitude is about 17.87 km; to automatically use the coarse grid, the ROMS grid needs to be of resolution < 17.87km / 2 = 8.9km
|
|
496
|
+
grid_10km = Grid(
|
|
497
|
+
nx=3, ny=3, size_x=30, size_y=30, center_lon=-10, center_lat=50, rot=0
|
|
498
|
+
)
|
|
499
|
+
surface_forcing = SurfaceForcing(
|
|
500
|
+
grid=grid_10km,
|
|
501
|
+
start_time=datetime(2020, 2, 1),
|
|
502
|
+
end_time=datetime(2020, 2, 2),
|
|
503
|
+
source={"name": "ERA5", "path": fname},
|
|
504
|
+
)
|
|
505
|
+
assert not surface_forcing.use_coarse_grid
|
|
506
|
+
|
|
507
|
+
grid_7km = Grid(
|
|
508
|
+
nx=3, ny=3, size_x=21, size_y=21, center_lon=-10, center_lat=50, rot=0
|
|
509
|
+
)
|
|
510
|
+
surface_forcing = SurfaceForcing(
|
|
511
|
+
grid=grid_7km,
|
|
512
|
+
start_time=datetime(2020, 2, 1),
|
|
513
|
+
end_time=datetime(2020, 2, 2),
|
|
514
|
+
source={"name": "ERA5", "path": fname},
|
|
515
|
+
)
|
|
516
|
+
assert surface_forcing.use_coarse_grid
|
|
517
|
+
|
|
518
|
+
# at 70N, 1/4 degree of longitude is about 9.5 km; to automatically use the coarse grid, the ROMS grid needs to be of resolution < 9.5km / 2 = 4.75km
|
|
519
|
+
grid_7km = Grid(
|
|
520
|
+
nx=3, ny=3, size_x=21, size_y=21, center_lon=-10, center_lat=70, rot=0
|
|
521
|
+
)
|
|
522
|
+
surface_forcing = SurfaceForcing(
|
|
523
|
+
grid=grid_7km,
|
|
524
|
+
start_time=datetime(2020, 2, 1),
|
|
525
|
+
end_time=datetime(2020, 2, 2),
|
|
526
|
+
source={"name": "ERA5", "path": fname},
|
|
527
|
+
)
|
|
528
|
+
assert not surface_forcing.use_coarse_grid
|
|
529
|
+
|
|
530
|
+
grid_4km = Grid(
|
|
531
|
+
nx=3, ny=3, size_x=12, size_y=12, center_lon=-10, center_lat=70, rot=0
|
|
532
|
+
)
|
|
533
|
+
surface_forcing = SurfaceForcing(
|
|
534
|
+
grid=grid_4km,
|
|
535
|
+
start_time=datetime(2020, 2, 1),
|
|
536
|
+
end_time=datetime(2020, 2, 2),
|
|
537
|
+
source={"name": "ERA5", "path": fname},
|
|
538
|
+
)
|
|
539
|
+
assert surface_forcing.use_coarse_grid
|
|
540
|
+
|
|
541
|
+
|
|
482
542
|
@pytest.mark.parametrize(
|
|
483
543
|
"sfc_forcing_fixture",
|
|
484
544
|
[
|
|
@@ -499,15 +559,15 @@ def test_surface_forcing_save(sfc_forcing_fixture, request, tmp_path):
|
|
|
499
559
|
str(tmp_path / file_str),
|
|
500
560
|
]: # test for Path object and str
|
|
501
561
|
|
|
502
|
-
# Test saving without
|
|
503
|
-
saved_filenames = sfc_forcing.save(filepath)
|
|
562
|
+
# Test saving without grouping
|
|
563
|
+
saved_filenames = sfc_forcing.save(filepath, group=False)
|
|
504
564
|
filepath_str = str(Path(filepath).with_suffix(""))
|
|
505
565
|
expected_filepath = Path(f"{filepath_str}.nc")
|
|
506
566
|
assert saved_filenames == [expected_filepath]
|
|
507
567
|
assert expected_filepath.exists()
|
|
508
568
|
expected_filepath.unlink()
|
|
509
569
|
|
|
510
|
-
# Test saving
|
|
570
|
+
# Test saving with grouping
|
|
511
571
|
saved_filenames = sfc_forcing.save(filepath, group=True)
|
|
512
572
|
filepath_str = str(Path(filepath).with_suffix(""))
|
|
513
573
|
expected_filepath = Path(f"{filepath_str}_202002.nc")
|
|
@@ -515,17 +575,6 @@ def test_surface_forcing_save(sfc_forcing_fixture, request, tmp_path):
|
|
|
515
575
|
assert expected_filepath.exists()
|
|
516
576
|
expected_filepath.unlink()
|
|
517
577
|
|
|
518
|
-
# Test saving with partitioning
|
|
519
|
-
saved_filenames = sfc_forcing.save(filepath, np_eta=1, group=True)
|
|
520
|
-
|
|
521
|
-
expected_filepath_list = [
|
|
522
|
-
Path(filepath_str + f"_202002.{index}.nc") for index in range(1)
|
|
523
|
-
]
|
|
524
|
-
assert saved_filenames == expected_filepath_list
|
|
525
|
-
for expected_filepath in expected_filepath_list:
|
|
526
|
-
assert expected_filepath.exists()
|
|
527
|
-
expected_filepath.unlink()
|
|
528
|
-
|
|
529
578
|
|
|
530
579
|
def test_surface_forcing_bgc_plot(bgc_surface_forcing):
|
|
531
580
|
"""Test plot method."""
|
|
@@ -543,15 +592,15 @@ def test_surface_forcing_bgc_save(bgc_surface_forcing, tmp_path):
|
|
|
543
592
|
str(tmp_path / file_str),
|
|
544
593
|
]: # test for Path object and str
|
|
545
594
|
|
|
546
|
-
# Test saving without
|
|
547
|
-
saved_filenames = bgc_surface_forcing.save(filepath)
|
|
595
|
+
# Test saving without grouping
|
|
596
|
+
saved_filenames = bgc_surface_forcing.save(filepath, group=False)
|
|
548
597
|
filepath_str = str(Path(filepath).with_suffix(""))
|
|
549
598
|
expected_filepath = Path(f"{filepath_str}.nc")
|
|
550
599
|
assert saved_filenames == [expected_filepath]
|
|
551
600
|
assert expected_filepath.exists()
|
|
552
601
|
expected_filepath.unlink()
|
|
553
602
|
|
|
554
|
-
# Test saving
|
|
603
|
+
# Test saving with grouping
|
|
555
604
|
saved_filenames = bgc_surface_forcing.save(filepath, group=True)
|
|
556
605
|
filepath_str = str(Path(filepath).with_suffix(""))
|
|
557
606
|
expected_filepath = Path(f"{filepath_str}_202002.nc")
|
|
@@ -559,17 +608,6 @@ def test_surface_forcing_bgc_save(bgc_surface_forcing, tmp_path):
|
|
|
559
608
|
assert expected_filepath.exists()
|
|
560
609
|
expected_filepath.unlink()
|
|
561
610
|
|
|
562
|
-
# Test saving with partitioning
|
|
563
|
-
saved_filenames = bgc_surface_forcing.save(filepath, np_xi=5, group=True)
|
|
564
|
-
|
|
565
|
-
expected_filepath_list = [
|
|
566
|
-
Path(filepath_str + f"_202002.{index}.nc") for index in range(5)
|
|
567
|
-
]
|
|
568
|
-
assert saved_filenames == expected_filepath_list
|
|
569
|
-
for expected_filepath in expected_filepath_list:
|
|
570
|
-
assert expected_filepath.exists()
|
|
571
|
-
expected_filepath.unlink()
|
|
572
|
-
|
|
573
611
|
|
|
574
612
|
def test_surface_forcing_bgc_from_clim_save(
|
|
575
613
|
bgc_surface_forcing_from_climatology, tmp_path
|
|
@@ -583,15 +621,17 @@ def test_surface_forcing_bgc_from_clim_save(
|
|
|
583
621
|
str(tmp_path / file_str),
|
|
584
622
|
]: # test for Path object and str
|
|
585
623
|
|
|
586
|
-
# Test saving without
|
|
587
|
-
saved_filenames = bgc_surface_forcing_from_climatology.save(
|
|
624
|
+
# Test saving without grouping
|
|
625
|
+
saved_filenames = bgc_surface_forcing_from_climatology.save(
|
|
626
|
+
filepath, group=False
|
|
627
|
+
)
|
|
588
628
|
filepath_str = str(Path(filepath).with_suffix(""))
|
|
589
629
|
expected_filepath = Path(f"{filepath_str}.nc")
|
|
590
630
|
assert saved_filenames == [expected_filepath]
|
|
591
631
|
assert expected_filepath.exists()
|
|
592
632
|
expected_filepath.unlink()
|
|
593
633
|
|
|
594
|
-
# Test saving
|
|
634
|
+
# Test saving with grouping
|
|
595
635
|
saved_filenames = bgc_surface_forcing_from_climatology.save(
|
|
596
636
|
filepath, group=True
|
|
597
637
|
)
|
|
@@ -601,19 +641,6 @@ def test_surface_forcing_bgc_from_clim_save(
|
|
|
601
641
|
assert expected_filepath.exists()
|
|
602
642
|
expected_filepath.unlink()
|
|
603
643
|
|
|
604
|
-
# Test saving with partitioning and grouping
|
|
605
|
-
saved_filenames = bgc_surface_forcing_from_climatology.save(
|
|
606
|
-
filepath, np_eta=5, group=True
|
|
607
|
-
)
|
|
608
|
-
|
|
609
|
-
expected_filepath_list = [
|
|
610
|
-
Path(filepath_str + f"_clim.{index}.nc") for index in range(5)
|
|
611
|
-
]
|
|
612
|
-
assert saved_filenames == expected_filepath_list
|
|
613
|
-
for expected_filepath in expected_filepath_list:
|
|
614
|
-
assert expected_filepath.exists()
|
|
615
|
-
expected_filepath.unlink()
|
|
616
|
-
|
|
617
644
|
|
|
618
645
|
@pytest.mark.parametrize(
|
|
619
646
|
"sfc_forcing_fixture",
|
|
@@ -675,8 +702,9 @@ def test_files_have_same_hash(sfc_forcing_fixture, request, tmp_path, use_dask):
|
|
|
675
702
|
expected_filepath1 = f"{filepath_str1}_202002.nc"
|
|
676
703
|
expected_filepath2 = f"{filepath_str2}_202002.nc"
|
|
677
704
|
|
|
678
|
-
|
|
679
|
-
|
|
705
|
+
# Only compare hash of datasets because metadata is non-deterministic with dask
|
|
706
|
+
hash1 = calculate_data_hash(expected_filepath1)
|
|
707
|
+
hash2 = calculate_data_hash(expected_filepath2)
|
|
680
708
|
|
|
681
709
|
assert hash1 == hash2, f"Hashes do not match: {hash1} != {hash2}"
|
|
682
710
|
|
|
@@ -703,8 +731,9 @@ def test_files_have_same_hash_clim(
|
|
|
703
731
|
expected_filepath1 = f"{filepath_str1}_clim.nc"
|
|
704
732
|
expected_filepath2 = f"{filepath_str2}_clim.nc"
|
|
705
733
|
|
|
706
|
-
|
|
707
|
-
|
|
734
|
+
# Only compare hash of datasets because metadata is non-deterministic with dask
|
|
735
|
+
hash1 = calculate_data_hash(expected_filepath1)
|
|
736
|
+
hash2 = calculate_data_hash(expected_filepath2)
|
|
708
737
|
|
|
709
738
|
assert hash1 == hash2, f"Hashes do not match: {hash1} != {hash2}"
|
|
710
739
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from roms_tools import Grid, TidalForcing
|
|
3
3
|
import xarray as xr
|
|
4
|
-
from roms_tools.
|
|
4
|
+
from roms_tools.download import download_test_data
|
|
5
5
|
import textwrap
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from conftest import
|
|
7
|
+
from conftest import calculate_data_hash
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@pytest.fixture
|
|
@@ -185,7 +185,6 @@ def test_tidal_forcing_save(tidal_forcing, tmp_path):
|
|
|
185
185
|
str(tmp_path / file_str),
|
|
186
186
|
]: # test for Path object and str
|
|
187
187
|
|
|
188
|
-
# Test saving without partitioning
|
|
189
188
|
saved_filenames = tidal_forcing.save(filepath)
|
|
190
189
|
# Check if the .nc file was created
|
|
191
190
|
filepath = Path(filepath).with_suffix(".nc")
|
|
@@ -194,18 +193,6 @@ def test_tidal_forcing_save(tidal_forcing, tmp_path):
|
|
|
194
193
|
# Clean up the .nc file
|
|
195
194
|
filepath.unlink()
|
|
196
195
|
|
|
197
|
-
# Test saving with partitioning
|
|
198
|
-
saved_filenames = tidal_forcing.save(filepath, np_eta=3, np_xi=3)
|
|
199
|
-
|
|
200
|
-
filepath_str = str(filepath.with_suffix(""))
|
|
201
|
-
expected_filepath_list = [
|
|
202
|
-
Path(filepath_str + f".{index}.nc") for index in range(9)
|
|
203
|
-
]
|
|
204
|
-
assert saved_filenames == expected_filepath_list
|
|
205
|
-
for expected_filepath in expected_filepath_list:
|
|
206
|
-
assert expected_filepath.exists()
|
|
207
|
-
expected_filepath.unlink()
|
|
208
|
-
|
|
209
196
|
|
|
210
197
|
def test_roundtrip_yaml(tidal_forcing, tmp_path, use_dask):
|
|
211
198
|
"""Test that creating a TidalForcing object, saving its parameters to yaml file, and
|
|
@@ -242,8 +229,9 @@ def test_files_have_same_hash(tidal_forcing, tmp_path, use_dask):
|
|
|
242
229
|
tidal_forcing_from_file = TidalForcing.from_yaml(yaml_filepath, use_dask=use_dask)
|
|
243
230
|
tidal_forcing_from_file.save(filepath2)
|
|
244
231
|
|
|
245
|
-
|
|
246
|
-
|
|
232
|
+
# Only compare hash of datasets because metadata is non-deterministic with dask
|
|
233
|
+
hash1 = calculate_data_hash(filepath1)
|
|
234
|
+
hash2 = calculate_data_hash(filepath2)
|
|
247
235
|
|
|
248
236
|
assert hash1 == hash2, f"Hashes do not match: {hash1} != {hash2}"
|
|
249
237
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from roms_tools import Grid
|
|
3
3
|
from roms_tools.setup.topography import _compute_rfactor
|
|
4
|
-
from roms_tools.
|
|
4
|
+
from roms_tools.download import download_test_data
|
|
5
5
|
import numpy as np
|
|
6
6
|
import numpy.testing as npt
|
|
7
7
|
from scipy.ndimage import label
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
from roms_tools import Grid, BoundaryForcing
|
|
1
2
|
from roms_tools.setup.utils import interpolate_from_climatology
|
|
2
3
|
from roms_tools.setup.datasets import ERA5Correction
|
|
3
|
-
from roms_tools.
|
|
4
|
+
from roms_tools.download import download_test_data
|
|
4
5
|
import xarray as xr
|
|
6
|
+
import pytest
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from pathlib import Path
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
def test_interpolate_from_climatology(use_dask):
|
|
@@ -11,6 +15,58 @@ def test_interpolate_from_climatology(use_dask):
|
|
|
11
15
|
|
|
12
16
|
climatology = ERA5Correction(use_dask=use_dask)
|
|
13
17
|
field = climatology.ds["ssr_corr"]
|
|
18
|
+
field["time"] = field["time"].dt.days
|
|
14
19
|
|
|
15
20
|
interpolated_field = interpolate_from_climatology(field, "time", era5_times)
|
|
16
21
|
assert len(interpolated_field.time) == len(era5_times)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Test yaml roundtrip with multiple source files
|
|
25
|
+
@pytest.fixture()
|
|
26
|
+
def boundary_forcing_from_multiple_source_files(request, use_dask):
|
|
27
|
+
"""Fixture for creating a BoundaryForcing object."""
|
|
28
|
+
|
|
29
|
+
grid = Grid(
|
|
30
|
+
nx=5,
|
|
31
|
+
ny=5,
|
|
32
|
+
size_x=100,
|
|
33
|
+
size_y=100,
|
|
34
|
+
center_lon=-8,
|
|
35
|
+
center_lat=60,
|
|
36
|
+
rot=10,
|
|
37
|
+
N=3, # number of vertical levels
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
fname1 = Path(download_test_data("GLORYS_NA_20120101.nc"))
|
|
41
|
+
fname2 = Path(download_test_data("GLORYS_NA_20121231.nc"))
|
|
42
|
+
|
|
43
|
+
return BoundaryForcing(
|
|
44
|
+
grid=grid,
|
|
45
|
+
start_time=datetime(2011, 1, 1),
|
|
46
|
+
end_time=datetime(2013, 1, 1),
|
|
47
|
+
source={"name": "GLORYS", "path": [fname1, fname2]},
|
|
48
|
+
use_dask=use_dask,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_roundtrip_yaml(
|
|
53
|
+
boundary_forcing_from_multiple_source_files, request, tmp_path, use_dask
|
|
54
|
+
):
|
|
55
|
+
"""Test that creating a BoundaryForcing object, saving its parameters to yaml file,
|
|
56
|
+
and re-opening yaml file creates the same object."""
|
|
57
|
+
|
|
58
|
+
# Create a temporary filepath using the tmp_path fixture
|
|
59
|
+
file_str = "test_yaml"
|
|
60
|
+
for filepath in [
|
|
61
|
+
tmp_path / file_str,
|
|
62
|
+
str(tmp_path / file_str),
|
|
63
|
+
]: # test for Path object and str
|
|
64
|
+
|
|
65
|
+
boundary_forcing_from_multiple_source_files.to_yaml(filepath)
|
|
66
|
+
|
|
67
|
+
bdry_forcing_from_file = BoundaryForcing.from_yaml(filepath, use_dask=use_dask)
|
|
68
|
+
|
|
69
|
+
assert boundary_forcing_from_multiple_source_files == bdry_forcing_from_file
|
|
70
|
+
|
|
71
|
+
filepath = Path(filepath)
|
|
72
|
+
filepath.unlink()
|