roms-tools 1.7.0__py3-none-any.whl → 2.1.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 +2 -1
- roms_tools/setup/boundary_forcing.py +246 -146
- roms_tools/setup/datasets.py +229 -69
- roms_tools/setup/download.py +13 -17
- roms_tools/setup/grid.py +777 -614
- roms_tools/setup/initial_conditions.py +168 -32
- roms_tools/setup/mask.py +115 -0
- roms_tools/setup/nesting.py +575 -0
- roms_tools/setup/plot.py +218 -63
- roms_tools/setup/regrid.py +4 -2
- roms_tools/setup/river_forcing.py +125 -29
- roms_tools/setup/surface_forcing.py +31 -25
- roms_tools/setup/tides.py +29 -14
- roms_tools/setup/topography.py +250 -153
- roms_tools/setup/utils.py +174 -44
- roms_tools/setup/vertical_coordinate.py +5 -16
- roms_tools/tests/test_setup/test_boundary_forcing.py +10 -5
- roms_tools/tests/test_setup/test_data/grid.zarr/.zattrs +0 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/.zmetadata +56 -201
- roms_tools/tests/test_setup/test_data/grid.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/Cs_w/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid.zarr/{layer_depth_rho → sigma_r}/.zarray +2 -6
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_r/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_r/0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_w/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_w/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/sigma_w/0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zattrs +1 -2
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/.zmetadata +58 -203
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/Cs_r/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/Cs_w/.zattrs +1 -1
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/h/.zattrs +1 -1
- 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/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/sigma_r/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_r/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_r/0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_w/.zarray +20 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_w/.zattrs +7 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/sigma_w/0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/.zmetadata +2 -3
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/river_tracer/.zattrs +1 -2
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/tracer_name/.zarray +1 -1
- roms_tools/tests/test_setup/test_data/river_forcing_no_climatology.zarr/tracer_name/0 +0 -0
- roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/.zmetadata +5 -6
- roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_tracer/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_tracer/.zattrs +1 -2
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/river_tracer/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/tracer_name/.zarray +2 -2
- roms_tools/tests/test_setup/test_data/river_forcing_with_bgc.zarr/tracer_name/0 +0 -0
- roms_tools/tests/test_setup/test_datasets.py +2 -2
- roms_tools/tests/test_setup/test_grid.py +110 -12
- roms_tools/tests/test_setup/test_initial_conditions.py +2 -1
- roms_tools/tests/test_setup/test_nesting.py +489 -0
- roms_tools/tests/test_setup/test_river_forcing.py +53 -15
- roms_tools/tests/test_setup/test_surface_forcing.py +3 -22
- roms_tools/tests/test_setup/test_tides.py +2 -1
- roms_tools/tests/test_setup/test_topography.py +106 -1
- roms_tools/tests/test_setup/test_validation.py +2 -2
- {roms_tools-1.7.0.dist-info → roms_tools-2.1.0.dist-info}/LICENSE +1 -1
- {roms_tools-1.7.0.dist-info → roms_tools-2.1.0.dist-info}/METADATA +9 -4
- {roms_tools-1.7.0.dist-info → roms_tools-2.1.0.dist-info}/RECORD +85 -108
- {roms_tools-1.7.0.dist-info → roms_tools-2.1.0.dist-info}/WHEEL +1 -1
- roms_tools/_version.py +0 -2
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_rho/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_u/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_v/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/interface_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_u/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_v/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid.zarr/layer_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_u/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_v/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/interface_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_rho/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_u/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/.zarray +0 -24
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/.zattrs +0 -9
- roms_tools/tests/test_setup/test_data/grid_that_straddles_dateline.zarr/layer_depth_v/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/river_tracer/0.0.0 +0 -0
- roms_tools/tests/test_setup/test_data/river_forcing.zarr/tracer_name/0 +0 -0
- roms_tools/tests/test_setup/test_vertical_coordinate.py +0 -91
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/.zgroup +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/abs_time/.zarray +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/abs_time/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/abs_time/0 +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/month/.zarray +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/month/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/month/0 +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_name/.zarray +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_name/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_name/0 +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_time/.zarray +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_time/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_time/0 +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_volume/.zarray +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_volume/.zattrs +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/river_volume/0.0 +0 -0
- /roms_tools/tests/test_setup/test_data/{river_forcing.zarr → river_forcing_with_bgc.zarr}/tracer_name/.zattrs +0 -0
- {roms_tools-1.7.0.dist-info → roms_tools-2.1.0.dist-info}/top_level.txt +0 -0
roms_tools/setup/utils.py
CHANGED
|
@@ -41,7 +41,7 @@ def nan_check(field, mask, error_message=None) -> None:
|
|
|
41
41
|
da = xr.where(mask == 1, field, 0)
|
|
42
42
|
if error_message is None:
|
|
43
43
|
error_message = (
|
|
44
|
-
"NaN values found in
|
|
44
|
+
"NaN values found in regridded field. This likely occurs because the ROMS grid, including "
|
|
45
45
|
"a small safety margin for interpolation, is not fully contained within the dataset's longitude/latitude range. Please ensure that the "
|
|
46
46
|
"dataset covers the entire area required by the ROMS grid."
|
|
47
47
|
)
|
|
@@ -107,10 +107,10 @@ def interpolate_from_rho_to_u(field, method="additive"):
|
|
|
107
107
|
else:
|
|
108
108
|
raise NotImplementedError(f"Unsupported method '{method}' specified.")
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
vars_to_drop = ["lat_rho", "lon_rho", "eta_rho", "xi_rho"]
|
|
111
|
+
for var in vars_to_drop:
|
|
112
|
+
if var in field_interpolated.coords:
|
|
113
|
+
field_interpolated = field_interpolated.drop_vars(var)
|
|
114
114
|
|
|
115
115
|
field_interpolated = field_interpolated.swap_dims({"xi_rho": "xi_u"})
|
|
116
116
|
|
|
@@ -155,10 +155,10 @@ def interpolate_from_rho_to_v(field, method="additive"):
|
|
|
155
155
|
else:
|
|
156
156
|
raise NotImplementedError(f"Unsupported method '{method}' specified.")
|
|
157
157
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
vars_to_drop = ["lat_rho", "lon_rho", "eta_rho", "xi_rho"]
|
|
159
|
+
for var in vars_to_drop:
|
|
160
|
+
if var in field_interpolated.coords:
|
|
161
|
+
field_interpolated = field_interpolated.drop_vars(var)
|
|
162
162
|
|
|
163
163
|
field_interpolated = field_interpolated.swap_dims({"eta_rho": "eta_v"})
|
|
164
164
|
|
|
@@ -733,27 +733,27 @@ def get_target_coords(grid, use_coarse_grid=False):
|
|
|
733
733
|
"""
|
|
734
734
|
# Select grid variables based on whether the coarse grid is used
|
|
735
735
|
if use_coarse_grid:
|
|
736
|
-
lat
|
|
737
|
-
|
|
738
|
-
grid.ds.lon_coarse.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}),
|
|
739
|
-
grid.ds.angle_coarse.rename(
|
|
740
|
-
{"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
|
|
741
|
-
),
|
|
742
|
-
grid.ds.mask_coarse.rename(
|
|
743
|
-
{"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
|
|
744
|
-
),
|
|
736
|
+
lat = grid.ds.lat_coarse.rename(
|
|
737
|
+
{"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
|
|
745
738
|
)
|
|
739
|
+
lon = grid.ds.lon_coarse.rename(
|
|
740
|
+
{"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
|
|
741
|
+
)
|
|
742
|
+
angle = grid.ds.angle_coarse.rename(
|
|
743
|
+
{"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"}
|
|
744
|
+
)
|
|
745
|
+
mask = grid.ds.get("mask_coarse")
|
|
746
|
+
if mask is not None:
|
|
747
|
+
mask = mask.rename({"eta_coarse": "eta_rho", "xi_coarse": "xi_rho"})
|
|
746
748
|
|
|
747
749
|
lat_psi = grid.ds.get("lat_psi_coarse")
|
|
748
750
|
lon_psi = grid.ds.get("lon_psi_coarse")
|
|
749
751
|
|
|
750
752
|
else:
|
|
751
|
-
lat
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
grid.ds.mask_rho,
|
|
756
|
-
)
|
|
753
|
+
lat = grid.ds.lat_rho
|
|
754
|
+
lon = grid.ds.lon_rho
|
|
755
|
+
angle = grid.ds.angle
|
|
756
|
+
mask = grid.ds.get("mask_rho")
|
|
757
757
|
lat_psi = grid.ds.get("lat_psi")
|
|
758
758
|
lon_psi = grid.ds.get("lon_psi")
|
|
759
759
|
|
|
@@ -927,37 +927,40 @@ def get_vector_pairs(variable_info):
|
|
|
927
927
|
return vector_pairs
|
|
928
928
|
|
|
929
929
|
|
|
930
|
-
def gc_dist(lon1, lat1, lon2, lat2):
|
|
931
|
-
"""Calculate the great circle distance between two points on the Earth's surface
|
|
932
|
-
|
|
933
|
-
radians).
|
|
930
|
+
def gc_dist(lon1, lat1, lon2, lat2, input_in_degrees=True):
|
|
931
|
+
"""Calculate the great circle distance between two points on the Earth's surface
|
|
932
|
+
using the Haversine formula.
|
|
934
933
|
|
|
935
|
-
|
|
936
|
-
|
|
934
|
+
Latitude and longitude are assumed to be in degrees by default. If `input_in_degrees` is set to `False`,
|
|
935
|
+
the input is assumed to already be in radians.
|
|
937
936
|
|
|
938
937
|
Parameters
|
|
939
938
|
----------
|
|
940
939
|
lon1, lat1 : float
|
|
941
|
-
Longitude and latitude of the first point
|
|
940
|
+
Longitude and latitude of the first point.
|
|
942
941
|
lon2, lat2 : float
|
|
943
|
-
Longitude and latitude of the second point
|
|
942
|
+
Longitude and latitude of the second point.
|
|
943
|
+
input_in_degrees : bool, optional
|
|
944
|
+
If True (default), the input coordinates are assumed to be in degrees and will be converted to radians.
|
|
945
|
+
If False, the input is assumed to be in radians and no conversion is applied.
|
|
944
946
|
|
|
945
947
|
Returns
|
|
946
948
|
-------
|
|
947
949
|
dis : float
|
|
948
950
|
The great circle distance between the two points in meters.
|
|
949
|
-
This is the shortest distance along the surface of a sphere (Earth).
|
|
950
951
|
|
|
951
952
|
Notes
|
|
952
953
|
-----
|
|
953
954
|
The radius of the Earth is taken to be 6371315 meters.
|
|
954
955
|
"""
|
|
956
|
+
|
|
955
957
|
# Convert degrees to radians
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
958
|
+
if input_in_degrees:
|
|
959
|
+
d2r = np.pi / 180
|
|
960
|
+
lon1 = lon1 * d2r
|
|
961
|
+
lat1 = lat1 * d2r
|
|
962
|
+
lon2 = lon2 * d2r
|
|
963
|
+
lat2 = lat2 * d2r
|
|
961
964
|
|
|
962
965
|
# Difference in latitudes and longitudes
|
|
963
966
|
dlat = lat2 - lat1
|
|
@@ -1058,11 +1061,17 @@ def _to_yaml(forcing_object, filepath: Union[str, Path]) -> None:
|
|
|
1058
1061
|
filepath = Path(filepath)
|
|
1059
1062
|
|
|
1060
1063
|
# Step 1: Serialize Grid data
|
|
1061
|
-
#
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1064
|
+
# Check if the forcing_object has a grid attribute
|
|
1065
|
+
if hasattr(forcing_object, "grid") and forcing_object.grid is not None:
|
|
1066
|
+
grid_data = asdict(forcing_object.grid)
|
|
1067
|
+
grid_yaml_data = {"Grid": _pop_grid_data(grid_data)}
|
|
1068
|
+
else:
|
|
1069
|
+
parent_grid_data = asdict(forcing_object.parent_grid)
|
|
1070
|
+
parent_grid_yaml_data = {"ParentGrid": _pop_grid_data(parent_grid_data)}
|
|
1071
|
+
child_grid_data = asdict(forcing_object.child_grid)
|
|
1072
|
+
child_grid_yaml_data = {"ChildGrid": _pop_grid_data(child_grid_data)}
|
|
1073
|
+
|
|
1074
|
+
grid_yaml_data = {**parent_grid_yaml_data, **child_grid_yaml_data}
|
|
1066
1075
|
|
|
1067
1076
|
# Step 2: Get ROMS Tools version
|
|
1068
1077
|
# Fetch the version of the 'roms-tools' package for inclusion in the YAML header
|
|
@@ -1081,7 +1090,16 @@ def _to_yaml(forcing_object, filepath: Union[str, Path]) -> None:
|
|
|
1081
1090
|
filtered_field_names = [
|
|
1082
1091
|
param
|
|
1083
1092
|
for param in field_names
|
|
1084
|
-
if param
|
|
1093
|
+
if param
|
|
1094
|
+
not in (
|
|
1095
|
+
"grid",
|
|
1096
|
+
"parent_grid",
|
|
1097
|
+
"child_grid",
|
|
1098
|
+
"ds",
|
|
1099
|
+
"use_dask",
|
|
1100
|
+
"bypass_validation",
|
|
1101
|
+
"climatology",
|
|
1102
|
+
)
|
|
1085
1103
|
]
|
|
1086
1104
|
|
|
1087
1105
|
for field_name in filtered_field_names:
|
|
@@ -1110,6 +1128,14 @@ def _to_yaml(forcing_object, filepath: Union[str, Path]) -> None:
|
|
|
1110
1128
|
yaml.dump(yaml_data, file, default_flow_style=False, sort_keys=False)
|
|
1111
1129
|
|
|
1112
1130
|
|
|
1131
|
+
def _pop_grid_data(grid_data):
|
|
1132
|
+
grid_data.pop("ds", None) # Remove 'ds' attribute (non-serializable)
|
|
1133
|
+
grid_data.pop("straddle", None)
|
|
1134
|
+
grid_data.pop("verbose", None)
|
|
1135
|
+
|
|
1136
|
+
return grid_data
|
|
1137
|
+
|
|
1138
|
+
|
|
1113
1139
|
def _from_yaml(forcing_object: Type, filepath: Union[str, Path]) -> Dict[str, Any]:
|
|
1114
1140
|
"""Extract the configuration data for a given forcing object from a YAML file.
|
|
1115
1141
|
|
|
@@ -1179,3 +1205,107 @@ def _convert_from_iso_format(value):
|
|
|
1179
1205
|
except ValueError:
|
|
1180
1206
|
# Return None or raise an exception if parsing fails
|
|
1181
1207
|
return value
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
def handle_boundaries(field):
|
|
1211
|
+
"""Adjust the boundaries of a 2D field by copying values from adjacent cells.
|
|
1212
|
+
|
|
1213
|
+
Parameters
|
|
1214
|
+
----------
|
|
1215
|
+
field : numpy.ndarray or xarray.DataArray
|
|
1216
|
+
A 2D array representing a field (e.g., topography or mask) whose boundary values
|
|
1217
|
+
need to be adjusted.
|
|
1218
|
+
|
|
1219
|
+
Returns
|
|
1220
|
+
-------
|
|
1221
|
+
field : numpy.ndarray or xarray.DataArray
|
|
1222
|
+
The input field with adjusted boundary values.
|
|
1223
|
+
"""
|
|
1224
|
+
|
|
1225
|
+
field[0, :] = field[1, :]
|
|
1226
|
+
field[-1, :] = field[-2, :]
|
|
1227
|
+
field[:, 0] = field[:, 1]
|
|
1228
|
+
field[:, -1] = field[:, -2]
|
|
1229
|
+
|
|
1230
|
+
return field
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
def get_boundary_coords():
|
|
1234
|
+
"""This function determines the boundary points for the grid variables by specifying
|
|
1235
|
+
the indices for the south, east, north, and west boundaries.
|
|
1236
|
+
|
|
1237
|
+
Returns
|
|
1238
|
+
-------
|
|
1239
|
+
dict
|
|
1240
|
+
A dictionary containing the boundary coordinates for different variable types.
|
|
1241
|
+
The dictionary has the following structure:
|
|
1242
|
+
- Keys: Variable types ("rho", "u", "v", "vector").
|
|
1243
|
+
- Values: Nested dictionaries that map each direction ("south", "east", "north", "west")
|
|
1244
|
+
to another dictionary specifying the boundary coordinates, represented by grid indices
|
|
1245
|
+
for the respective variable types. For example:
|
|
1246
|
+
- "rho" variables (e.g., `eta_rho`, `xi_rho`)
|
|
1247
|
+
- "u" variables (e.g., `xi_u`)
|
|
1248
|
+
- "v" variables (e.g., `eta_v`)
|
|
1249
|
+
- "vector" variables with lists of indices for multiple grid points (e.g., `eta_rho`, `xi_rho`).
|
|
1250
|
+
"""
|
|
1251
|
+
|
|
1252
|
+
bdry_coords = {
|
|
1253
|
+
"rho": {
|
|
1254
|
+
"south": {"eta_rho": 0},
|
|
1255
|
+
"east": {"xi_rho": -1},
|
|
1256
|
+
"north": {"eta_rho": -1},
|
|
1257
|
+
"west": {"xi_rho": 0},
|
|
1258
|
+
},
|
|
1259
|
+
"u": {
|
|
1260
|
+
"south": {"eta_rho": 0},
|
|
1261
|
+
"east": {"xi_u": -1},
|
|
1262
|
+
"north": {"eta_rho": -1},
|
|
1263
|
+
"west": {"xi_u": 0},
|
|
1264
|
+
},
|
|
1265
|
+
"v": {
|
|
1266
|
+
"south": {"eta_v": 0},
|
|
1267
|
+
"east": {"xi_rho": -1},
|
|
1268
|
+
"north": {"eta_v": -1},
|
|
1269
|
+
"west": {"xi_rho": 0},
|
|
1270
|
+
},
|
|
1271
|
+
"vector": {
|
|
1272
|
+
"south": {"eta_rho": [0, 1]},
|
|
1273
|
+
"east": {"xi_rho": [-2, -1]},
|
|
1274
|
+
"north": {"eta_rho": [-2, -1]},
|
|
1275
|
+
"west": {"xi_rho": [0, 1]},
|
|
1276
|
+
},
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
return bdry_coords
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
def wrap_longitudes(grid_ds, straddle):
|
|
1283
|
+
"""Adjusts longitude values in a dataset to handle dateline crossing.
|
|
1284
|
+
|
|
1285
|
+
Parameters
|
|
1286
|
+
----------
|
|
1287
|
+
grid_ds : xr.Dataset
|
|
1288
|
+
The dataset containing longitude variables to adjust.
|
|
1289
|
+
straddle : bool
|
|
1290
|
+
If True, adjusts longitudes to the range [-180, 180] for datasets
|
|
1291
|
+
that straddle the dateline. If False, adjusts longitudes to the
|
|
1292
|
+
range [0, 360].
|
|
1293
|
+
|
|
1294
|
+
Returns
|
|
1295
|
+
-------
|
|
1296
|
+
xr.Dataset
|
|
1297
|
+
The dataset with adjusted longitude values.
|
|
1298
|
+
"""
|
|
1299
|
+
for lon_dim in ["lon_rho", "lon_u", "lon_v"]:
|
|
1300
|
+
if straddle:
|
|
1301
|
+
grid_ds[lon_dim] = xr.where(
|
|
1302
|
+
grid_ds[lon_dim] > 180,
|
|
1303
|
+
grid_ds[lon_dim] - 360,
|
|
1304
|
+
grid_ds[lon_dim],
|
|
1305
|
+
)
|
|
1306
|
+
else:
|
|
1307
|
+
grid_ds[lon_dim] = xr.where(
|
|
1308
|
+
grid_ds[lon_dim] < 0, grid_ds[lon_dim] + 360, grid_ds[lon_dim]
|
|
1309
|
+
)
|
|
1310
|
+
|
|
1311
|
+
return grid_ds
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import xarray as xr
|
|
3
|
+
from roms_tools.setup.utils import transpose_dimensions
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def compute_cs(sigma, theta_s, theta_b):
|
|
@@ -83,7 +84,7 @@ def compute_depth(zeta, h, hc, cs, sigma):
|
|
|
83
84
|
|
|
84
85
|
Parameters
|
|
85
86
|
----------
|
|
86
|
-
zeta : xr.DataArray
|
|
87
|
+
zeta : xr.DataArray or scalar
|
|
87
88
|
The sea surface height.
|
|
88
89
|
h : xr.DataArray
|
|
89
90
|
The depth of the sea bottom.
|
|
@@ -98,23 +99,11 @@ def compute_depth(zeta, h, hc, cs, sigma):
|
|
|
98
99
|
-------
|
|
99
100
|
z : xr.DataArray
|
|
100
101
|
The depth at different sigma levels.
|
|
101
|
-
|
|
102
|
-
Raises
|
|
103
|
-
------
|
|
104
|
-
ValueError
|
|
105
|
-
If theta_s or theta_b are less than or equal to zero.
|
|
106
102
|
"""
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
cs = cs.expand_dims(dim={"eta_rho": h.eta_rho, "xi_rho": h.xi_rho})
|
|
111
|
-
|
|
112
|
-
s = (hc * sigma + h * cs) / (hc + h)
|
|
113
|
-
z = zeta + (zeta + h) * s
|
|
104
|
+
z = (hc * sigma + h * cs) / (hc + h)
|
|
105
|
+
z = zeta + (zeta + h) * z
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
z = z.transpose("s_rho", "eta_rho", "xi_rho")
|
|
117
|
-
elif "s_w" in z.dims:
|
|
118
|
-
z = z.transpose("s_w", "eta_rho", "xi_rho")
|
|
107
|
+
z = -transpose_dimensions(z)
|
|
119
108
|
|
|
120
109
|
return z
|
|
@@ -241,10 +241,14 @@ def test_boundary_forcing_save(boundary_forcing, tmp_path):
|
|
|
241
241
|
def test_bgc_boundary_forcing_plot(bgc_boundary_forcing_from_climatology):
|
|
242
242
|
"""Test plot method."""
|
|
243
243
|
|
|
244
|
-
bgc_boundary_forcing_from_climatology.plot(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
bgc_boundary_forcing_from_climatology.plot(var_name="
|
|
244
|
+
bgc_boundary_forcing_from_climatology.plot(
|
|
245
|
+
var_name="ALK_south", layer_contours=True
|
|
246
|
+
)
|
|
247
|
+
bgc_boundary_forcing_from_climatology.plot(var_name="ALK_east", layer_contours=True)
|
|
248
|
+
bgc_boundary_forcing_from_climatology.plot(
|
|
249
|
+
var_name="ALK_north", layer_contours=True
|
|
250
|
+
)
|
|
251
|
+
bgc_boundary_forcing_from_climatology.plot(var_name="ALK_west", layer_contours=True)
|
|
248
252
|
|
|
249
253
|
|
|
250
254
|
def test_bgc_boundary_forcing_save(bgc_boundary_forcing_from_climatology, tmp_path):
|
|
@@ -390,7 +394,8 @@ def test_from_yaml_missing_boundary_forcing(tmp_path, request, use_dask):
|
|
|
390
394
|
center_lon: -10
|
|
391
395
|
center_lat: 61
|
|
392
396
|
rot: -20
|
|
393
|
-
topography_source:
|
|
397
|
+
topography_source:
|
|
398
|
+
name: ETOPO5
|
|
394
399
|
hmin: 5.0
|
|
395
400
|
"""
|
|
396
401
|
)
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
".zattrs": {
|
|
4
4
|
"center_lat": 0,
|
|
5
5
|
"center_lon": -20,
|
|
6
|
-
"coordinates": "interface_depth_rho interface_depth_u interface_depth_v layer_depth_rho layer_depth_u layer_depth_v",
|
|
7
6
|
"hc": 300.0,
|
|
8
7
|
"hmin": 5.0,
|
|
9
8
|
"roms_tools_version": "0.1.dev157+dirty",
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
"_ARRAY_DIMENSIONS": [
|
|
43
42
|
"s_rho"
|
|
44
43
|
],
|
|
45
|
-
"long_name": "
|
|
44
|
+
"long_name": "Vertical stretching function at rho-points",
|
|
46
45
|
"units": "nondimensional"
|
|
47
46
|
},
|
|
48
47
|
"Cs_w/.zarray": {
|
|
@@ -69,7 +68,7 @@
|
|
|
69
68
|
"_ARRAY_DIMENSIONS": [
|
|
70
69
|
"s_w"
|
|
71
70
|
],
|
|
72
|
-
"long_name": "
|
|
71
|
+
"long_name": "Vertical stretching function at w-points",
|
|
73
72
|
"units": "nondimensional"
|
|
74
73
|
},
|
|
75
74
|
"angle/.zarray": {
|
|
@@ -196,105 +195,6 @@
|
|
|
196
195
|
"long_name": "Final bathymetry at rho-points",
|
|
197
196
|
"units": "meter"
|
|
198
197
|
},
|
|
199
|
-
"interface_depth_rho/.zarray": {
|
|
200
|
-
"chunks": [
|
|
201
|
-
101,
|
|
202
|
-
3,
|
|
203
|
-
3
|
|
204
|
-
],
|
|
205
|
-
"compressor": {
|
|
206
|
-
"blocksize": 0,
|
|
207
|
-
"clevel": 5,
|
|
208
|
-
"cname": "lz4",
|
|
209
|
-
"id": "blosc",
|
|
210
|
-
"shuffle": 1
|
|
211
|
-
},
|
|
212
|
-
"dtype": "<f4",
|
|
213
|
-
"fill_value": "NaN",
|
|
214
|
-
"filters": null,
|
|
215
|
-
"order": "C",
|
|
216
|
-
"shape": [
|
|
217
|
-
101,
|
|
218
|
-
3,
|
|
219
|
-
3
|
|
220
|
-
],
|
|
221
|
-
"zarr_format": 2
|
|
222
|
-
},
|
|
223
|
-
"interface_depth_rho/.zattrs": {
|
|
224
|
-
"_ARRAY_DIMENSIONS": [
|
|
225
|
-
"s_w",
|
|
226
|
-
"eta_rho",
|
|
227
|
-
"xi_rho"
|
|
228
|
-
],
|
|
229
|
-
"long_name": "Interface depth at rho-points",
|
|
230
|
-
"units": "m"
|
|
231
|
-
},
|
|
232
|
-
"interface_depth_u/.zarray": {
|
|
233
|
-
"chunks": [
|
|
234
|
-
101,
|
|
235
|
-
3,
|
|
236
|
-
2
|
|
237
|
-
],
|
|
238
|
-
"compressor": {
|
|
239
|
-
"blocksize": 0,
|
|
240
|
-
"clevel": 5,
|
|
241
|
-
"cname": "lz4",
|
|
242
|
-
"id": "blosc",
|
|
243
|
-
"shuffle": 1
|
|
244
|
-
},
|
|
245
|
-
"dtype": "<f4",
|
|
246
|
-
"fill_value": "NaN",
|
|
247
|
-
"filters": null,
|
|
248
|
-
"order": "C",
|
|
249
|
-
"shape": [
|
|
250
|
-
101,
|
|
251
|
-
3,
|
|
252
|
-
2
|
|
253
|
-
],
|
|
254
|
-
"zarr_format": 2
|
|
255
|
-
},
|
|
256
|
-
"interface_depth_u/.zattrs": {
|
|
257
|
-
"_ARRAY_DIMENSIONS": [
|
|
258
|
-
"s_w",
|
|
259
|
-
"eta_rho",
|
|
260
|
-
"xi_u"
|
|
261
|
-
],
|
|
262
|
-
"long_name": "Interface depth at u-points",
|
|
263
|
-
"units": "m"
|
|
264
|
-
},
|
|
265
|
-
"interface_depth_v/.zarray": {
|
|
266
|
-
"chunks": [
|
|
267
|
-
101,
|
|
268
|
-
2,
|
|
269
|
-
3
|
|
270
|
-
],
|
|
271
|
-
"compressor": {
|
|
272
|
-
"blocksize": 0,
|
|
273
|
-
"clevel": 5,
|
|
274
|
-
"cname": "lz4",
|
|
275
|
-
"id": "blosc",
|
|
276
|
-
"shuffle": 1
|
|
277
|
-
},
|
|
278
|
-
"dtype": "<f4",
|
|
279
|
-
"fill_value": "NaN",
|
|
280
|
-
"filters": null,
|
|
281
|
-
"order": "C",
|
|
282
|
-
"shape": [
|
|
283
|
-
101,
|
|
284
|
-
2,
|
|
285
|
-
3
|
|
286
|
-
],
|
|
287
|
-
"zarr_format": 2
|
|
288
|
-
},
|
|
289
|
-
"interface_depth_v/.zattrs": {
|
|
290
|
-
"_ARRAY_DIMENSIONS": [
|
|
291
|
-
"s_w",
|
|
292
|
-
"eta_v",
|
|
293
|
-
"xi_rho"
|
|
294
|
-
],
|
|
295
|
-
"long_name": "Interface depth at v-points",
|
|
296
|
-
"units": "m"
|
|
297
|
-
},
|
|
298
198
|
"lat_coarse/.zarray": {
|
|
299
199
|
"chunks": [
|
|
300
200
|
2,
|
|
@@ -415,105 +315,6 @@
|
|
|
415
315
|
"long_name": "latitude of v-points",
|
|
416
316
|
"units": "degrees North"
|
|
417
317
|
},
|
|
418
|
-
"layer_depth_rho/.zarray": {
|
|
419
|
-
"chunks": [
|
|
420
|
-
100,
|
|
421
|
-
3,
|
|
422
|
-
3
|
|
423
|
-
],
|
|
424
|
-
"compressor": {
|
|
425
|
-
"blocksize": 0,
|
|
426
|
-
"clevel": 5,
|
|
427
|
-
"cname": "lz4",
|
|
428
|
-
"id": "blosc",
|
|
429
|
-
"shuffle": 1
|
|
430
|
-
},
|
|
431
|
-
"dtype": "<f4",
|
|
432
|
-
"fill_value": "NaN",
|
|
433
|
-
"filters": null,
|
|
434
|
-
"order": "C",
|
|
435
|
-
"shape": [
|
|
436
|
-
100,
|
|
437
|
-
3,
|
|
438
|
-
3
|
|
439
|
-
],
|
|
440
|
-
"zarr_format": 2
|
|
441
|
-
},
|
|
442
|
-
"layer_depth_rho/.zattrs": {
|
|
443
|
-
"_ARRAY_DIMENSIONS": [
|
|
444
|
-
"s_rho",
|
|
445
|
-
"eta_rho",
|
|
446
|
-
"xi_rho"
|
|
447
|
-
],
|
|
448
|
-
"long_name": "Layer depth at rho-points",
|
|
449
|
-
"units": "m"
|
|
450
|
-
},
|
|
451
|
-
"layer_depth_u/.zarray": {
|
|
452
|
-
"chunks": [
|
|
453
|
-
100,
|
|
454
|
-
3,
|
|
455
|
-
2
|
|
456
|
-
],
|
|
457
|
-
"compressor": {
|
|
458
|
-
"blocksize": 0,
|
|
459
|
-
"clevel": 5,
|
|
460
|
-
"cname": "lz4",
|
|
461
|
-
"id": "blosc",
|
|
462
|
-
"shuffle": 1
|
|
463
|
-
},
|
|
464
|
-
"dtype": "<f4",
|
|
465
|
-
"fill_value": "NaN",
|
|
466
|
-
"filters": null,
|
|
467
|
-
"order": "C",
|
|
468
|
-
"shape": [
|
|
469
|
-
100,
|
|
470
|
-
3,
|
|
471
|
-
2
|
|
472
|
-
],
|
|
473
|
-
"zarr_format": 2
|
|
474
|
-
},
|
|
475
|
-
"layer_depth_u/.zattrs": {
|
|
476
|
-
"_ARRAY_DIMENSIONS": [
|
|
477
|
-
"s_rho",
|
|
478
|
-
"eta_rho",
|
|
479
|
-
"xi_u"
|
|
480
|
-
],
|
|
481
|
-
"long_name": "Layer depth at u-points",
|
|
482
|
-
"units": "m"
|
|
483
|
-
},
|
|
484
|
-
"layer_depth_v/.zarray": {
|
|
485
|
-
"chunks": [
|
|
486
|
-
100,
|
|
487
|
-
2,
|
|
488
|
-
3
|
|
489
|
-
],
|
|
490
|
-
"compressor": {
|
|
491
|
-
"blocksize": 0,
|
|
492
|
-
"clevel": 5,
|
|
493
|
-
"cname": "lz4",
|
|
494
|
-
"id": "blosc",
|
|
495
|
-
"shuffle": 1
|
|
496
|
-
},
|
|
497
|
-
"dtype": "<f4",
|
|
498
|
-
"fill_value": "NaN",
|
|
499
|
-
"filters": null,
|
|
500
|
-
"order": "C",
|
|
501
|
-
"shape": [
|
|
502
|
-
100,
|
|
503
|
-
2,
|
|
504
|
-
3
|
|
505
|
-
],
|
|
506
|
-
"zarr_format": 2
|
|
507
|
-
},
|
|
508
|
-
"layer_depth_v/.zattrs": {
|
|
509
|
-
"_ARRAY_DIMENSIONS": [
|
|
510
|
-
"s_rho",
|
|
511
|
-
"eta_v",
|
|
512
|
-
"xi_rho"
|
|
513
|
-
],
|
|
514
|
-
"long_name": "Layer depth at v-points",
|
|
515
|
-
"units": "m"
|
|
516
|
-
},
|
|
517
318
|
"lon_coarse/.zarray": {
|
|
518
319
|
"chunks": [
|
|
519
320
|
2,
|
|
@@ -820,6 +621,60 @@
|
|
|
820
621
|
"long_name": "Curvilinear coordinate metric in eta-direction",
|
|
821
622
|
"units": "meter-1"
|
|
822
623
|
},
|
|
624
|
+
"sigma_r/.zarray": {
|
|
625
|
+
"chunks": [
|
|
626
|
+
100
|
|
627
|
+
],
|
|
628
|
+
"compressor": {
|
|
629
|
+
"blocksize": 0,
|
|
630
|
+
"clevel": 5,
|
|
631
|
+
"cname": "lz4",
|
|
632
|
+
"id": "blosc",
|
|
633
|
+
"shuffle": 1
|
|
634
|
+
},
|
|
635
|
+
"dtype": "<f4",
|
|
636
|
+
"fill_value": "NaN",
|
|
637
|
+
"filters": null,
|
|
638
|
+
"order": "C",
|
|
639
|
+
"shape": [
|
|
640
|
+
100
|
|
641
|
+
],
|
|
642
|
+
"zarr_format": 2
|
|
643
|
+
},
|
|
644
|
+
"sigma_r/.zattrs": {
|
|
645
|
+
"_ARRAY_DIMENSIONS": [
|
|
646
|
+
"s_rho"
|
|
647
|
+
],
|
|
648
|
+
"long_name": "Fractional vertical stretching coordinate at rho-points",
|
|
649
|
+
"units": "nondimensional"
|
|
650
|
+
},
|
|
651
|
+
"sigma_w/.zarray": {
|
|
652
|
+
"chunks": [
|
|
653
|
+
101
|
|
654
|
+
],
|
|
655
|
+
"compressor": {
|
|
656
|
+
"blocksize": 0,
|
|
657
|
+
"clevel": 5,
|
|
658
|
+
"cname": "lz4",
|
|
659
|
+
"id": "blosc",
|
|
660
|
+
"shuffle": 1
|
|
661
|
+
},
|
|
662
|
+
"dtype": "<f4",
|
|
663
|
+
"fill_value": "NaN",
|
|
664
|
+
"filters": null,
|
|
665
|
+
"order": "C",
|
|
666
|
+
"shape": [
|
|
667
|
+
101
|
|
668
|
+
],
|
|
669
|
+
"zarr_format": 2
|
|
670
|
+
},
|
|
671
|
+
"sigma_w/.zattrs": {
|
|
672
|
+
"_ARRAY_DIMENSIONS": [
|
|
673
|
+
"s_w"
|
|
674
|
+
],
|
|
675
|
+
"long_name": "Fractional vertical stretching coordinate at w-points",
|
|
676
|
+
"units": "nondimensional"
|
|
677
|
+
},
|
|
823
678
|
"spherical/.zarray": {
|
|
824
679
|
"chunks": [],
|
|
825
680
|
"compressor": null,
|