Skip to content

Commit

Permalink
Add product.convention
Browse files Browse the repository at this point in the history
  • Loading branch information
lassebje committed Nov 11, 2024
1 parent 10af70f commit b1b3744
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 0 deletions.
21 changes: 21 additions & 0 deletions metocean_api/ts/internal/convention.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from enum import Enum, auto

class Convention(Enum):
"""
Convention used for the provided data.
NONE: No convention used
OCEANIC: Oceanic convention - Direction to
- Follows clockwise rotation from geographic North (0 degrees). East is in 90 degrees
- Determines the direction towards which natural elements, e.g., waves/wind/currents, are moving to.
METEOROLOGICAL: Meteorological or Nautical convention - Direction from
- Follows clockwise rotation from geographic North (0 degrees). East is in 90 degrees
- Determines the direction where natural elements, e.g., waves/wind/currents, are coming from.
"""
NONE = auto()
OCEANIC = auto()
METEOROLOGICAL = auto()
5 changes: 5 additions & 0 deletions metocean_api/ts/internal/ec/ec_products.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import xarray as xr
import numpy as np
from ..product import Product
from ..convention import Convention

from .. import aux_funcs

Expand All @@ -23,6 +24,10 @@ def find_product(name: str) -> Product:


class ERA5(Product):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=False):
"""
Expand Down
57 changes: 57 additions & 0 deletions metocean_api/ts/internal/metno/met_products.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .met_product import MetProduct

from ..product import Product
from ..convention import Convention
from .. import aux_funcs

if TYPE_CHECKING:
Expand Down Expand Up @@ -52,6 +53,10 @@ def find_product(name: str) -> Product:

class Nora3Wave(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC

def get_default_variables(self):
return [
"hs",
Expand Down Expand Up @@ -108,6 +113,10 @@ def _get_url_info(self, date: str):

class NORA3WindSub(MetProduct):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def get_default_variables(self):
return ["wind_speed", "wind_direction"]

Expand Down Expand Up @@ -138,6 +147,11 @@ def _alter_temporary_dataset_if_needed(self, dataset: xr.Dataset):

class NORA3WindWaveCombined(MetProduct):

@property
def convention(self) -> Convention:
# This is a combined product, so we cannot determine the convention
return Convention.NONE

def get_default_variables(self):
raise NotImplementedError("This method should not be called")

Expand Down Expand Up @@ -218,6 +232,10 @@ def download_temporary_files(self, ts: TimeSeries, use_cache: bool = False) -> T


class NORACWave(MetProduct):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def get_default_variables(self):
return [
Expand Down Expand Up @@ -257,6 +275,10 @@ def _get_near_coord(self, url: str, lon: float, lat: float):

class NORA3AtmSub(MetProduct):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def get_default_variables(self):
return [
"air_pressure_at_sea_level",
Expand Down Expand Up @@ -289,6 +311,10 @@ def _get_near_coord(self, url: str, lon: float, lat: float):

class NORA3Atm3hrSub(MetProduct):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def get_default_variables(self):
return [
"wind_speed",
Expand Down Expand Up @@ -319,6 +345,10 @@ def _get_near_coord(self, url: str, lon: float, lat: float):

class NORA3StormSurge(MetProduct):

@property
def convention(self) -> Convention:
return Convention.NONE

def get_default_variables(self):
return ["zeta"]

Expand Down Expand Up @@ -381,6 +411,11 @@ def _drop_variables(self):

class Norkyst800(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC


def get_default_variables(self):
return ["salinity", "temperature", "u", "v", "zeta"]

Expand Down Expand Up @@ -452,6 +487,11 @@ def _flatten_data_structure(self, ds: xr.Dataset, **flatten_dims):

class NorkystDASurface(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC


def get_default_variables(self):
return ["u", "v", "zeta", "temp", "salt"]

Expand Down Expand Up @@ -492,6 +532,11 @@ def _drop_variables(self):

class NorkystDAZdepth(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC


def get_default_variables(self):
return ["u", "v", "zeta", "temp", "salt", "AKs"]

Expand Down Expand Up @@ -533,6 +578,10 @@ def _drop_variables(self):

class NORA3WaveSpectrum(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC

def get_default_variables(self):
return ["SPEC"]

Expand Down Expand Up @@ -601,6 +650,10 @@ def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=Fa

class NORACWaveSpectrum(MetProduct):

@property
def convention(self) -> Convention:
return Convention.OCEANIC

def get_default_variables(self):
return ["efth"]

Expand Down Expand Up @@ -663,6 +716,10 @@ def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=Fa

class E39Observations(MetProduct):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def get_default_variables(self):
return ["Hm0"]

Expand Down
5 changes: 5 additions & 0 deletions metocean_api/ts/internal/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Tuple, List
from abc import ABC, abstractmethod
from .convention import Convention

if TYPE_CHECKING:
from ts.ts_mod import TimeSeries # Only imported for type checking
Expand All @@ -14,6 +15,10 @@ class Product(ABC):
def __init__(self, name: str):
self.name = name

@property
def convention(self) -> Convention:
return Convention.NONE

@abstractmethod
def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=False):
"""Import data specified by the TimeSeries object"""
Expand Down
5 changes: 5 additions & 0 deletions metocean_api/ts/internal/tudelft/tudelft_products.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from .. import aux_funcs
from ..product import Product
from ..convention import Convention
if TYPE_CHECKING:
from ts.ts_mod import TimeSeries # Only imported for type checking

Expand All @@ -20,6 +21,10 @@ def find_product(name: str) -> Product:

class EchoWave(Product):

@property
def convention(self) -> Convention:
return Convention.METEOROLOGICAL

def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=False):
"""
Extract times series of the nearest gird point (lon,lat) from
Expand Down
5 changes: 5 additions & 0 deletions tests/test_extract_data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import xarray as xr
from metocean_api import ts
from metocean_api.ts.internal import products
from metocean_api.ts.internal.convention import Convention

# Switches useful for local testing
USE_CACHE = False
Expand All @@ -10,6 +11,10 @@
def test_extract_nora3_wind():
df_ts = ts.TimeSeries(lon=1.320, lat=53.324,start_time='2000-01-01', end_time='2000-01-31', product='NORA3_wind_sub')
# Import data from thredds.met.no
product = products.find_product(df_ts.product)
assert product.name == df_ts.product
assert product.convention == Convention.METEOROLOGICAL

df_ts.import_data(save_csv=SAVE_CSV,save_nc=SAVE_NC, use_cache=USE_CACHE)
assert (df_ts.lat_data, df_ts.lon_data) == (53.32374838481946, 1.3199893172215793)
assert df_ts.data.shape == (744,14)
Expand Down

0 comments on commit b1b3744

Please sign in to comment.