Skip to content

Commit 6dde2c7

Browse files
authored
Merge pull request #110 from MET-OM/dev-cmems-tide
Dev cmems tide
2 parents 287be98 + 5973ef2 commit 6dde2c7

5 files changed

Lines changed: 112 additions & 8 deletions

File tree

dnora/read/cmems_functions.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ def ds_cmems_read(
3737
maximum_latitude=lat[1],
3838
start_datetime=start_time.strftime("%Y-%m-%dT%H:%M:00"),
3939
end_datetime=end_time.strftime("%Y-%m-%dT%H:%M:00"),
40-
minimum_depth=kwargs.get('minimum_depth'),
41-
maximum_depth=kwargs.get('maximum_depth'),
40+
minimum_depth=kwargs.get('minimum_depth',0),
41+
maximum_depth=kwargs.get('maximum_depth',0),
4242

4343
)
44-
4544
return ds

dnora/read/current/cmems.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ class Global(ProductReader):
2727
ds_cmems_read,
2828
dataset_id="cmems_obs-mob_glo_phy-cur_my_0.25deg_PT1H-i",
2929
variables=["uo","vo"],
30-
minimum_depth=0,
31-
maximum_depth=0,
3230
),
3331
ds_aliases={"uo": gp.ocean.XCurrent, "vo": gp.ocean.YCurrent},
3432
default_data_source=DataSource.REMOTE,
@@ -37,4 +35,37 @@ class Global(ProductReader):
3735
file_structure = FileStructure()
3836

3937
def post_processing(self):
40-
return FillNaNs(0)
38+
return FillNaNs(0)
39+
40+
@deprecated_class_call("CMEMS", "cmems", "current")
41+
class EuropeNW(ProductReader):
42+
"""The ocean physics reanalysis for the North-West European Shelf is produced using an ocean assimilation model, with tides, at 7 km horizontal resolution.
43+
The ocean model is NEMO (Nucleus for European Modelling of the Ocean), using the 3DVar NEMOVAR system to assimilate observations.
44+
These are surface temperature and vertical profiles of temperature and salinity. The model is forced by lateral boundary conditions from the
45+
GloSea5, one of the multi-models used by GLOBAL_REANALYSIS_PHY_001_026 and at the Baltic boundary by the BALTICSEA_REANALYSIS_PHY_003_011.
46+
The atmospheric forcing is given by the ECMWF ERA5 atmospheric reanalysis. The river discharge is from a daily climatology.
47+
48+
49+
Note: This reader reads the hourly 2D surface fields of surface currents.
50+
51+
DOI (product): https://doi.org/10.48670/moi-00059
52+
https://data.marine.copernicus.eu/product/NWSHELF_MULTIYEAR_PHY_004_009/description
53+
"""
54+
55+
product_configuration = ProductConfiguration(
56+
ds_creator_function=partial(
57+
ds_cmems_read,
58+
dataset_id="cmems_mod_nws_phy-uv_my_7km-2D_PT1H-i",
59+
variables=["uo","vo"],
60+
),
61+
ds_aliases={"uo": gp.ocean.XCurrent, "vo": gp.ocean.YCurrent},
62+
default_data_source=DataSource.REMOTE,
63+
)
64+
65+
file_structure = FileStructure()
66+
67+
def post_processing(self):
68+
return FillNaNs(0)
69+
70+
71+

dnora/read/waterlevel/cmems.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,32 @@ class Global(ProductReader):
3939

4040
def post_processing(self):
4141
return FillNaNs(0)
42+
43+
@deprecated_class_call("CMEMS", "cmems", "waterlevel")
44+
class EuropeNW(ProductReader):
45+
"""The ocean physics reanalysis for the North-West European Shelf is produced using an ocean assimilation model, with tides, at 7 km horizontal resolution.
46+
The ocean model is NEMO (Nucleus for European Modelling of the Ocean), using the 3DVar NEMOVAR system to assimilate observations.
47+
These are surface temperature and vertical profiles of temperature and salinity. The model is forced by lateral boundary conditions from the
48+
GloSea5, one of the multi-models used by GLOBAL_REANALYSIS_PHY_001_026 and at the Baltic boundary by the BALTICSEA_REANALYSIS_PHY_003_011.
49+
The atmospheric forcing is given by the ECMWF ERA5 atmospheric reanalysis. The river discharge is from a daily climatology.
50+
51+
52+
Note: This reader reads the hourly 2D surface fields of sea surface height.
53+
54+
DOI (product): https://doi.org/10.48670/moi-00059
55+
https://data.marine.copernicus.eu/product/NWSHELF_MULTIYEAR_PHY_004_009/description
56+
"""
57+
58+
product_configuration = ProductConfiguration(
59+
ds_creator_function=partial(
60+
ds_cmems_read,
61+
dataset_id="cmems_mod_nws_phy-ssh_my_7km-2D_PT1H-i",
62+
variables=["zos"],
63+
),
64+
default_data_source=DataSource.REMOTE,
65+
)
66+
67+
file_structure = FileStructure()
68+
69+
def post_processing(self):
70+
return FillNaNs(0)

tests/test_readers/test_remote_current_readers.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,22 @@
22
import pytest
33
import pandas as pd
44
import numpy as np
5+
import os, shutil
56

67

8+
def grid_is_covered(grid, skeleton):
9+
assert skeleton.lon()[0] < grid.lon()[0]
10+
assert skeleton.lon()[-1] >= grid.lon()[-1]
11+
assert skeleton.lat()[0] < grid.lat()[0]
12+
assert skeleton.lat()[-1] >= grid.lat()[-1]
713
@pytest.fixture(scope="session")
814
def grid():
915
return dn.grid.Grid(lon=(10, 14), lat=(60, 61))
1016

17+
@pytest.fixture(scope="session")
18+
def grid2():
19+
return dn.grid.Grid(lon=(4, 6), lat=(58, 61))
20+
1121

1222
@pytest.fixture(scope="session")
1323
def grid160():
@@ -23,7 +33,9 @@ def timevec():
2333
def timevec2017():
2434
return pd.date_range("2017-04-01 00:00:00", "2017-04-01 23:00:00", freq="1h")
2535

26-
36+
def cleanup():
37+
if os.path.isdir("dnora_current_temp"):
38+
shutil.rmtree("dnora_current_temp")
2739
@pytest.mark.remote
2840
def test_norkyst800(grid, timevec):
2941
model = dn.modelrun.ModelRun(grid, year=2022, month=4, day=1)
@@ -52,3 +64,25 @@ def test_norfjords160(grid160, timevec):
5264
assert np.all(model.current().time() == timevec)
5365
assert model.current().u(strict=True) is not None
5466
assert model.current().v(strict=True) is not None
67+
68+
@pytest.mark.remote
69+
def test_cmems_global(grid, timevec):
70+
cleanup()
71+
model = dn.modelrun.ModelRun(grid, year=2022, month=4, day=1)
72+
model.import_current(dn.read.current.cmems.Global(), expansion_factor=1.5)
73+
74+
assert np.all(model.current().time() == timevec)
75+
76+
grid_is_covered(grid, model.current())
77+
cleanup()
78+
79+
80+
@pytest.mark.remote
81+
def test_cmems_europe(grid2, timevec):
82+
cleanup()
83+
model = dn.modelrun.ModelRun(grid2, year=2022, month=4, day=1)
84+
model.import_current(dn.read.current.cmems.EuropeNW())
85+
assert np.all(model.current().time() == timevec)
86+
87+
grid_is_covered(grid2, model.current())
88+
cleanup()

tests/test_readers/test_remote_waterlevel_readers.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,22 @@ def test_era5(grid, timevec):
4040

4141

4242
@pytest.mark.remote
43-
def test_cmems(grid, timevec):
43+
def test_cmems_global(grid, timevec):
4444
cleanup()
4545
model = dn.modelrun.ModelRun(grid, year=2023, month=4, day=1)
4646
model.import_waterlevel(dn.read.waterlevel.cmems.Global())
4747
assert np.all(model.waterlevel().time() == timevec)
4848

49+
grid_is_covered(grid, model.waterlevel())
50+
cleanup()
51+
52+
53+
@pytest.mark.remote
54+
def test_cmems_europe(grid, timevec):
55+
cleanup()
56+
model = dn.modelrun.ModelRun(grid, year=2023, month=4, day=1)
57+
model.import_waterlevel(dn.read.waterlevel.cmems.EuropeNW())
58+
assert np.all(model.waterlevel().time() == timevec)
59+
4960
grid_is_covered(grid, model.waterlevel())
5061
cleanup()

0 commit comments

Comments
 (0)