diff --git a/parcels/fieldset.py b/parcels/fieldset.py index 9b3761775..95df62349 100644 --- a/parcels/fieldset.py +++ b/parcels/fieldset.py @@ -230,21 +230,25 @@ def from_copernicusmarine(ds: xr.Dataset): ) ) - U = Field("U", ds["U"], grid) - V = Field("V", ds["V"], grid) - - U.units = GeographicPolar() - V.units = Geographic() + fields = {} + if "U" in ds.data_vars and "V" in ds.data_vars: + fields["U"] = Field("U", ds["U"], grid) + fields["V"] = Field("V", ds["V"], grid) + fields["U"].units = GeographicPolar() + fields["V"].units = Geographic() + + if "W" in ds.data_vars: + ds["W"] -= ds[ + "W" + ] # Negate W to convert from up positive to down positive (as that's the direction of positive depth) + fields["W"] = Field("W", ds["W"], grid) + fields["UVW"] = VectorField("UVW", fields["U"], fields["V"], fields["W"]) + else: + fields["UV"] = VectorField("UV", fields["U"], fields["V"]) - fields = {"U": U, "V": V} for varname in set(ds.data_vars) - set(fields.keys()): fields[varname] = Field(varname, ds[varname], grid) - if "U" in fields and "V" in fields: - if "W" in fields: - fields["UVW"] = VectorField("UVW", fields["U"], fields["V"], fields["W"]) - else: - fields["UV"] = VectorField("UV", fields["U"], fields["V"]) return FieldSet(list(fields.values())) @@ -324,6 +328,13 @@ def _discover_copernicusmarine_U_and_V(ds: xr.Dataset) -> xr.Dataset: "northward_sea_water_velocity_vertical_mean_over_pelagic_layer", ), # GLOBAL_MULTIYEAR_BGC_001_033 ] + cf_W_standard_name_fallbacks = ["upward_sea_water_velocity", "vertical_sea_water_velocity"] + + if "W" not in ds: + for cf_standard_name_W in cf_W_standard_name_fallbacks: + if cf_standard_name_W in ds.cf.standard_names: + ds = _ds_rename_using_standard_names(ds, {cf_standard_name_W: "W"}) + break if "U" in ds and "V" in ds: return ds # U and V already present @@ -345,12 +356,6 @@ def _discover_copernicusmarine_U_and_V(ds: xr.Dataset) -> xr.Dataset: ds = _ds_rename_using_standard_names(ds, {cf_standard_name_U: "U", cf_standard_name_V: "V"}) break - else: - raise ValueError( - f"Could not find variables 'U' and 'V' in dataset, nor any of the fallback CF standard names " - f"{cf_UV_standard_name_fallbacks}. Please rename the appropriate variables to 'U' and 'V' in " - "your dataset for the Parcels simulation." - ) return ds diff --git a/tests/v4/test_fieldset.py b/tests/v4/test_fieldset.py index 4dac8ffdd..0787886be 100644 --- a/tests/v4/test_fieldset.py +++ b/tests/v4/test_fieldset.py @@ -1,5 +1,6 @@ from datetime import timedelta +import cf_xarray # noqa: F401 import cftime import numpy as np import pytest @@ -232,6 +233,17 @@ def test_fieldset_from_copernicusmarine(ds, caplog): assert "renamed it to 'V'" in caplog.text +def test_fieldset_from_copernicusmarine_no_currents(caplog): + ds = datasets_circulation_models["ds_copernicusmarine"].cf.drop_vars( + ["eastward_sea_water_velocity", "northward_sea_water_velocity"] + ) + fieldset = FieldSet.from_copernicusmarine(ds) + assert "U" not in fieldset.fields + assert "V" not in fieldset.fields + assert "UV" not in fieldset.fields + assert caplog.text == "" + + @pytest.mark.parametrize("ds", _COPERNICUS_DATASETS) def test_fieldset_from_copernicusmarine_no_logs(ds, caplog): ds = ds.copy() @@ -244,3 +256,18 @@ def test_fieldset_from_copernicusmarine_no_logs(ds, caplog): assert "V" in fieldset.fields assert "UV" in fieldset.fields assert caplog.text == "" + + +def test_fieldset_from_copernicusmarine_with_W(caplog): + ds = datasets_circulation_models["ds_copernicusmarine"] + ds = ds.copy() + ds["wo"] = ds["uo"] + ds["wo"].attrs["standard_name"] = "vertical_sea_water_velocity" + + fieldset = FieldSet.from_copernicusmarine(ds) + assert "U" in fieldset.fields + assert "V" in fieldset.fields + assert "W" in fieldset.fields + assert "UV" not in fieldset.fields + assert "UVW" in fieldset.fields + assert "renamed it to 'W'" in caplog.text