wavespectra 4.3.0__tar.gz → 4.4.0__tar.gz

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.
Files changed (72) hide show
  1. {wavespectra-4.3.0/wavespectra.egg-info → wavespectra-4.4.0}/PKG-INFO +3 -2
  2. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/__init__.py +1 -1
  3. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/utils.py +15 -0
  4. wavespectra-4.4.0/wavespectra/input/era5.py +114 -0
  5. {wavespectra-4.3.0 → wavespectra-4.4.0/wavespectra.egg-info}/PKG-INFO +3 -2
  6. wavespectra-4.3.0/wavespectra/input/era5.py +0 -92
  7. {wavespectra-4.3.0 → wavespectra-4.4.0}/AUTHORS.rst +0 -0
  8. {wavespectra-4.3.0 → wavespectra-4.4.0}/LICENSE.txt +0 -0
  9. {wavespectra-4.3.0 → wavespectra-4.4.0}/README.rst +0 -0
  10. {wavespectra-4.3.0 → wavespectra-4.4.0}/pyproject.toml +0 -0
  11. {wavespectra-4.3.0 → wavespectra-4.4.0}/setup.cfg +0 -0
  12. {wavespectra-4.3.0 → wavespectra-4.4.0}/setup.py +0 -0
  13. {wavespectra-4.3.0 → wavespectra-4.4.0}/tests/test_cli.py +0 -0
  14. {wavespectra-4.3.0 → wavespectra-4.4.0}/tests/test_cookiecutter_template.py +0 -0
  15. {wavespectra-4.3.0 → wavespectra-4.4.0}/tests/test_partition.py +0 -0
  16. {wavespectra-4.3.0 → wavespectra-4.4.0}/tests/test_specarray.py +0 -0
  17. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/cli.py +0 -0
  18. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/construct/__init__.py +0 -0
  19. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/construct/direction.py +0 -0
  20. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/construct/frequency.py +0 -0
  21. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/__init__.py +0 -0
  22. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/attributes.py +0 -0
  23. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/attributes.yml +0 -0
  24. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/fitting.py +0 -0
  25. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/npstats.py +0 -0
  26. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/select.py +0 -0
  27. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/swan.py +0 -0
  28. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/core/xrstats.py +0 -0
  29. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/__init__.py +0 -0
  30. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/awac.py +0 -0
  31. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/dataset.py +0 -0
  32. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/datawell.py +0 -0
  33. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/funwave.py +0 -0
  34. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/json.py +0 -0
  35. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/ncswan.py +0 -0
  36. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/ndbc.py +0 -0
  37. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/ndbc_ascii.py +0 -0
  38. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/netcdf.py +0 -0
  39. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/obscape.py +0 -0
  40. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/octopus.py +0 -0
  41. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/spotter.py +0 -0
  42. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/swan.py +0 -0
  43. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/triaxys.py +0 -0
  44. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/wavespectra.py +0 -0
  45. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/ww3.py +0 -0
  46. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/ww3_station.py +0 -0
  47. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/wwm.py +0 -0
  48. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/input/xwaves.py +0 -0
  49. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/__init__.py +0 -0
  50. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/funwave.py +0 -0
  51. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/json.py +0 -0
  52. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/netcdf.py +0 -0
  53. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/octopus.py +0 -0
  54. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/orcaflex.py +0 -0
  55. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/swan.py +0 -0
  56. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/ww3.py +0 -0
  57. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/output/ww3.yml +0 -0
  58. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/__init__.py +0 -0
  59. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/hanson_and_phillips_2001.py +0 -0
  60. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/partition.py +0 -0
  61. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/specpart/specpart.c +0 -0
  62. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/specpart/specpart.h +0 -0
  63. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/specpart/specpart_wrap.c +0 -0
  64. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/partition/tracking.py +0 -0
  65. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/plot.py +0 -0
  66. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/specarray.py +0 -0
  67. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra/specdataset.py +0 -0
  68. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra.egg-info/SOURCES.txt +0 -0
  69. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra.egg-info/dependency_links.txt +0 -0
  70. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra.egg-info/entry_points.txt +0 -0
  71. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra.egg-info/requires.txt +0 -0
  72. {wavespectra-4.3.0 → wavespectra-4.4.0}/wavespectra.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: wavespectra
3
- Version: 4.3.0
3
+ Version: 4.4.0
4
4
  Summary: Library for ocean wave spectra
5
5
  Author-email: Wavespectra Developers <r.guedes@oceanum.science>
6
6
  Maintainer-email: Rafael Guedes <r.guedes@oceanum.science>, Tom Durrant <t.durrant@oceanum.science>
@@ -76,6 +76,7 @@ Requires-Dist: sphinx; extra == "docs"
76
76
  Requires-Dist: sphinx-autobuild; extra == "docs"
77
77
  Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
78
78
  Requires-Dist: sphinx-gallery; extra == "docs"
79
+ Dynamic: license-file
79
80
 
80
81
  wavespectra
81
82
  ===========
@@ -14,7 +14,7 @@ except ImportError:
14
14
  warnings.warn("Cannot import accessors at the main module level")
15
15
 
16
16
 
17
- __version__ = "4.3.0"
17
+ __version__ = "4.4.0"
18
18
 
19
19
 
20
20
  def _import_functions(pkgname="input", prefix="read"):
@@ -15,6 +15,21 @@ D2R = np.pi / 180.0
15
15
  R2D = 180.0 / np.pi
16
16
 
17
17
 
18
+ def create_frequencies(f0: float, nf: int, df: float = 1.1) -> np.ndarray:
19
+ """Create an array of logarithmically spaced frequencies.
20
+
21
+ Args:
22
+ - f0 (float): First frequency value in Hz (e.g., 0.03453)
23
+ - nf (int): Number of frequencies to generate
24
+ - df (float, optional): Multiplicative increment between frequencies. Defaults to 1.1.
25
+
26
+ Returns:
27
+ - np.ndarray: Array of frequencies in Hz
28
+
29
+ """
30
+ return f0 * (df ** np.arange(nf))
31
+
32
+
18
33
  def angle(dir1, dir2):
19
34
  """Relative angle between two directions.
20
35
 
@@ -0,0 +1,114 @@
1
+ """Read ERA5 2D Wave Spectra NetCDF files"""
2
+
3
+ import numpy as np
4
+ import xarray as xr
5
+ from xarray.backends import BackendEntrypoint
6
+
7
+ from wavespectra.core.utils import create_frequencies
8
+ from wavespectra.core.attributes import attrs, set_spec_attributes
9
+
10
+
11
+ MAPPING = {
12
+ "time": attrs.TIMENAME,
13
+ "valid_time": attrs.TIMENAME,
14
+ "frequency": attrs.FREQNAME,
15
+ "frequencyNumber": attrs.FREQNAME,
16
+ "direction": attrs.DIRNAME,
17
+ "directionNumber": attrs.DIRNAME,
18
+ "d2fd": attrs.SPECNAME,
19
+ "longitude": attrs.LONNAME,
20
+ "latitude": attrs.LATNAME,
21
+ }
22
+
23
+
24
+ def read_era5(filename_or_fileglob, chunks={}, f0=0.03453, df=1.1, as_site=False):
25
+ """Read Spectra from ECMWF ERA5 netCDF format.
26
+
27
+ Args:
28
+ - filename_or_fileglob (str, list, filelike): filename, fileglob specifying multiple
29
+ files, or filelike object to read.
30
+ - chunks (dict): chunk sizes for dimensions in dataset. By default
31
+ dataset is loaded using single chunk for all dimensions (see
32
+ xr.open_mfdataset documentation).
33
+ - f0 (float): First frequency value in Hz (e.g., 0.03453)
34
+ - df (float): Multiplicative increment between frequencies.
35
+ - as_site (bool): If True locations are defined by 1D site dimension.
36
+
37
+ Returns:
38
+ - dset (SpecDataset): spectra dataset object read from netcdf file.
39
+
40
+ Note:
41
+ - This reader also supports ECMWF spectra from the operational forecast.
42
+ - Documentation describing how to construct the spectral grid can be found at
43
+ https://www.ecmwf.int/en/forecasts/documentation-and-support/2d-wave-spectra.
44
+ - If file is large to fit in memory, consider specifying chunks for
45
+ 'time' and/or 'latitude/longitude' dims.
46
+
47
+ """
48
+
49
+ dset = xr.open_dataset(filename_or_fileglob).chunk(chunks)
50
+ return from_era5(dset, f0=f0, df=df, as_site=as_site)
51
+
52
+
53
+ def from_era5(dset, f0=0.03453, df=1.1, as_site=False):
54
+ """Format ERA5 netcdf dataset to receive wavespectra accessor.
55
+
56
+ Args:
57
+ - dset (xr.Dataset): Dataset created from a ERA5 netcdf file.
58
+ - f0 (float): First frequency value in Hz (e.g., 0.03453)
59
+ - df (float): Multiplicative increment between frequencies.
60
+ - as_site (bool): If True locations are defined by 1D site dimension.
61
+
62
+ Returns:
63
+ - Formated dataset with the SpecDataset accessor in the `spec` namespace.
64
+
65
+ """
66
+
67
+ mapping = {k: v for k, v in MAPPING.items() if k != v and k in dset.variables}
68
+ dset = dset.rename(mapping).reset_coords(drop=True)
69
+
70
+ # Convert ERA5 format to wavespectra format
71
+ dset[attrs.SPECNAME] = 10 ** dset[attrs.SPECNAME] * np.pi / 180
72
+ dset[attrs.SPECNAME] = dset[attrs.SPECNAME].fillna(0)
73
+
74
+ # Assign the logarithmic frequency grid
75
+ dset[attrs.FREQNAME] = create_frequencies(f0, dset[attrs.FREQNAME].size, df)
76
+
77
+ # Assign the coming-from direction grid
78
+ dd = 360 / dset[attrs.DIRNAME].size
79
+ dset[attrs.DIRNAME] = ((np.arange(0, 360, dd) + dd / 2) + 180) % 360
80
+
81
+ # Stack lat/lon dimensions if as_site is True
82
+ if as_site:
83
+ dset = (
84
+ dset.stack(site=[attrs.LATNAME, attrs.LONNAME], create_index=False)
85
+ .reset_coords()
86
+ .transpose(attrs.TIMENAME, attrs.SITENAME, attrs.FREQNAME, attrs.DIRNAME)
87
+ )
88
+
89
+ # Setting standard attributes
90
+ set_spec_attributes(dset)
91
+
92
+ return dset
93
+
94
+
95
+ class ERA5BackendEntrypoint(BackendEntrypoint):
96
+ """ERA5 backend engine."""
97
+
98
+ def open_dataset(
99
+ self,
100
+ filename_or_obj,
101
+ *,
102
+ drop_variables=None,
103
+ f0=0.03453,
104
+ df=1.1,
105
+ as_site=False,
106
+ ):
107
+ return read_era5(filename_or_obj, f0=f0, df=df)
108
+
109
+ def guess_can_open(self, filename_or_obj):
110
+ return False
111
+
112
+ description = "Open ERA5 netcdf spectra files as a wavespectra dataset."
113
+
114
+ url = "https://github.com/wavespectra/wavespectra"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: wavespectra
3
- Version: 4.3.0
3
+ Version: 4.4.0
4
4
  Summary: Library for ocean wave spectra
5
5
  Author-email: Wavespectra Developers <r.guedes@oceanum.science>
6
6
  Maintainer-email: Rafael Guedes <r.guedes@oceanum.science>, Tom Durrant <t.durrant@oceanum.science>
@@ -76,6 +76,7 @@ Requires-Dist: sphinx; extra == "docs"
76
76
  Requires-Dist: sphinx-autobuild; extra == "docs"
77
77
  Requires-Dist: sphinx-autodoc-typehints; extra == "docs"
78
78
  Requires-Dist: sphinx-gallery; extra == "docs"
79
+ Dynamic: license-file
79
80
 
80
81
  wavespectra
81
82
  ===========
@@ -1,92 +0,0 @@
1
- """Read ERA5 2D Wave Spectra NetCDF files"""
2
-
3
- import numpy as np
4
- from xarray.backends import BackendEntrypoint
5
-
6
- from wavespectra.core.attributes import attrs, set_spec_attributes
7
- from wavespectra.input.netcdf import read_netcdf
8
-
9
-
10
- DEFAULT_FREQS = np.full(30, 0.03453) * (1.1 ** np.arange(0, 30))
11
- DEFAULT_DIRS = (np.arange(7.5, 352.5 + 15, 15) + 180) % 360
12
-
13
-
14
- def read_era5(filename_or_fileglob, chunks={}, freqs=None, dirs=None):
15
- """Read Spectra from ECMWF ERA5 netCDF format.
16
-
17
- Args:
18
- - filename_or_fileglob (str, list, filelike): filename, fileglob specifying multiple
19
- files, or filelike object to read.
20
- - chunks (dict): chunk sizes for dimensions in dataset. By default
21
- dataset is loaded using single chunk for all dimensions (see
22
- xr.open_mfdataset documentation).
23
- - freqs (list): list of frequencies. By default use all 30 ERA5 frequencies.
24
- - dirs (list): list of directions. By default use all 24 ERA5 directions.
25
-
26
- Returns:
27
- - dset (SpecDataset): spectra dataset object read from netcdf file.
28
-
29
- Note:
30
- - Frequency and diirection coordinates seem to have only integer positions
31
- which is why they are allowed to be specified as a parameter.
32
- - If file is large to fit in memory, consider specifying chunks for
33
- 'time' and/or 'station' dims.
34
-
35
- """
36
-
37
- dset = read_netcdf(
38
- filename_or_fileglob,
39
- specname="d2fd",
40
- freqname="frequency",
41
- dirname="direction",
42
- lonname="longitude",
43
- latname="latitude",
44
- timename="time",
45
- chunks=chunks,
46
- )
47
- return from_era5(dset, freqs=freqs, dirs=dirs)
48
-
49
-
50
- def from_era5(dset, freqs=None, dirs=None):
51
- """Format ERA5 netcdf dataset to receive wavespectra accessor.
52
-
53
- Args:
54
- - dset (xr.Dataset): Dataset created from a SWAN netcdf file.
55
-
56
- Returns:
57
- - Formated dataset with the SpecDataset accessor in the `spec` namespace.
58
-
59
- """
60
-
61
- # Convert ERA5 format to wavespectra format
62
- dset = 10**dset * np.pi / 180
63
- dset = dset.fillna(0)
64
-
65
- dset[attrs.FREQNAME] = freqs if freqs else DEFAULT_FREQS
66
- dset[attrs.DIRNAME] = dirs if dirs else DEFAULT_DIRS
67
-
68
- # Setting standard attributes
69
- set_spec_attributes(dset)
70
-
71
- return dset
72
-
73
-
74
- class ERA5BackendEntrypoint(BackendEntrypoint):
75
- """ERA5 backend engine."""
76
-
77
- def open_dataset(
78
- self,
79
- filename_or_obj,
80
- *,
81
- drop_variables=None,
82
- freqs=None,
83
- dirs=None,
84
- ):
85
- return read_era5(filename_or_obj, freqs=freqs, dirs=dirs)
86
-
87
- def guess_can_open(self, filename_or_obj):
88
- return False
89
-
90
- description = "Open ERA5 netcdf spectra files as a wavespectra dataset."
91
-
92
- url = "https://github.com/wavespectra/wavespectra"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes