eo-tides 0.6.3.dev1__tar.gz → 0.6.3.dev3__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 (76) hide show
  1. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/PKG-INFO +1 -1
  2. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/setup.md +13 -3
  3. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/pyproject.toml +1 -1
  4. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/conftest.py +70 -4
  5. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/test_utils.py +14 -10
  6. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/testing.ipynb +83 -31
  7. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.editorconfig +0 -0
  8. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/actions/setup-python-env/action.yml +0 -0
  11. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/workflows/check-links.yml +0 -0
  12. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/workflows/main.yml +0 -0
  13. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/workflows/on-release-main.yml +0 -0
  14. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.github/workflows/paper.yml +0 -0
  15. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.gitignore +0 -0
  16. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/.pre-commit-config.yaml +0 -0
  17. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/CITATION.cff +0 -0
  18. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/CONTRIBUTING.md +0 -0
  19. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/Dockerfile +0 -0
  20. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/LICENSE +0 -0
  21. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/Makefile +0 -0
  22. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/README.md +0 -0
  23. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/codecov.yaml +0 -0
  24. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/api.md +0 -0
  25. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/dtu23_download.jpg +0 -0
  26. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eo-tides-abstract.gif +0 -0
  27. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eo-tides-logo-128.png +0 -0
  28. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eo-tides-logo-256.png +0 -0
  29. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eo-tides-logo.gif +0 -0
  30. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eo-tides-logo.png +0 -0
  31. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/eot20_download.jpg +0 -0
  32. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/fes_ftp.jpg +0 -0
  33. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/fes_myproducts.jpg +0 -0
  34. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/fes_productselection.jpg +0 -0
  35. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/fes_subscriptions.jpg +0 -0
  36. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/got_download.jpg +0 -0
  37. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/tide_models_clipped.jpg +0 -0
  38. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/assets/tpxo_download.jpg +0 -0
  39. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/changelog.md +0 -0
  40. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/credits.md +0 -0
  41. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/index.md +0 -0
  42. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/install.md +0 -0
  43. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/migration.md +0 -0
  44. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/notebooks/Case_study_intertidal.ipynb +0 -0
  45. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/notebooks/Model_tides.ipynb +0 -0
  46. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/notebooks/Satellite_data.ipynb +0 -0
  47. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/notebooks/Tide_statistics.ipynb +0 -0
  48. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/notebooks/Validating_tides.ipynb +0 -0
  49. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/docs/stylesheets/extra.css +0 -0
  50. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/__init__.py +0 -0
  51. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/eo.py +0 -0
  52. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/model.py +0 -0
  53. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/stats.py +0 -0
  54. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/utils.py +0 -0
  55. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/eo_tides/validation.py +0 -0
  56. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/mkdocs.yml +0 -0
  57. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/benchmarking.ipynb +0 -0
  58. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/figures/joss_abstract.png +0 -0
  59. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/figures/joss_fig_gesla.png +0 -0
  60. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/figures/joss_fig_list.png +0 -0
  61. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/figures/joss_fig_pixel.png +0 -0
  62. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/figures/joss_fig_stats.png +0 -0
  63. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/paper.bib +0 -0
  64. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/paper.md +0 -0
  65. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/paper/paper.pdf +0 -0
  66. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/GESLA3_ALL 2.csv +0 -0
  67. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/IDO71013_2020.csv +0 -0
  68. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/broome-62650-aus-bom +0 -0
  69. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/san_diego_ca-569a-usa-uhslc +0 -0
  70. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/sydney_fort_denison-60370-aus-bom +0 -0
  71. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/data/tide_models.tar.gz +0 -0
  72. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/test_eo.py +0 -0
  73. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/test_model.py +0 -0
  74. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/test_stats.py +0 -0
  75. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/tests/test_validation.py +0 -0
  76. {eo_tides-0.6.3.dev1 → eo_tides-0.6.3.dev3}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eo-tides
3
- Version: 0.6.3.dev1
3
+ Version: 0.6.3.dev3
4
4
  Summary: Tide modelling tools for large-scale satellite earth observation analysis
5
5
  Project-URL: Homepage, https://GeoscienceAustralia.github.io/eo-tides/
6
6
  Project-URL: Repository, https://github.com/GeoscienceAustralia/eo-tides
@@ -2,20 +2,30 @@
2
2
 
3
3
  !!! important
4
4
 
5
- `eo-tides` provides tools for modelling tides using global ocean tide models but does not host or maintain the models themselves. **Users are responsible for accessing, using, and citing ocean tide models in compliance with each model's licensing terms.**
5
+ `eo-tides` provides tools for modelling tides using global ocean tide models but does not host or maintain the model data itself. **Users are responsible for accessing, using, and citing ocean tide model data in compliance with each model's licensing terms.**
6
6
 
7
- Once you [have installed `eo-tides`](install.md), we need to download and set up the external global ocean tide models required for `eo-tides` to work.
7
+ Once you [have installed `eo-tides`](install.md), we need to download and set up the external global ocean tide model data required for `eo-tides` to work.
8
8
  The following documentation provides instructions for getting started with several common global ocean tide models.
9
9
 
10
10
  !!! tip
11
11
 
12
12
  Please refer to the [`pyTMD` documentation](https://pytmd.readthedocs.io/en/latest/getting_started/Getting-Started.html#directories) for additional instructions covering all other supported tide models.
13
13
 
14
+ ## Tide model files and harmonic tidal constituents
15
+
16
+ Tides are driven by complex gravitational interactions between the Earth, moon, and sun, which create periodic and predictable variations in sea level. These variations can be decomposed into a set of **harmonic tidal constituents** (also known as "tidal constants") with unique amplitudes and phases that correspond to different celestial influences.
17
+
18
+ **When downloading tide model data, you are retrieving these tidal constituents rather than direct modelled or measured tidal height outputs.** Global ocean tide models use amplitudes and phases from these tidal constituents to precisely reconstruct tidal variations, allowing them to predict tide heights for any location on the planet and any moment in time — even into the future.
19
+
20
+ !!! tip
21
+
22
+ For a deep dive into the science of tide modelling and how harmonic tidal constituents are used by global ocean tide models, refer to [`pyTMD` Ocean and Load Tides documentation.](https://pytmd.readthedocs.io/en/latest/background/Tides.html)
23
+
14
24
  ## Setting up a tide model directory
15
25
 
16
26
  As a first step, we need to create a directory that will contain our tide model data.
17
27
  This directory will be accessed by all `eo-tides` functions.
18
- For example, we might want to store our tide models in a directory called `tide_models/`:
28
+ For example, we might want to store our tide model data in a directory called `tide_models/`:
19
29
 
20
30
  ```
21
31
  tide_models/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "eo-tides"
3
- version = "0.6.3.dev1"
3
+ version = "0.6.3.dev3"
4
4
  description = "Tide modelling tools for large-scale satellite earth observation analysis"
5
5
  authors = [
6
6
  { name = "Robbi Bishop-Taylor" },
@@ -105,7 +105,7 @@ def satellite_ds(satellite_ds_load):
105
105
  # Run once per session to generate symethic HAMTIDE11 files; autouse=True
106
106
  # allows this to run without being specifically called in tests
107
107
  @pytest.fixture(scope="session", autouse=True)
108
- def create_synthetic_model(base_dir="tests/data/tide_models_synthetic"):
108
+ def create_synthetic_hamtide11(base_dir="tests/data/tide_models_synthetic"):
109
109
  """
110
110
  Generates and exports synthetic HAMTIDE11 model data
111
111
  to test clipping functionality.
@@ -116,16 +116,16 @@ def create_synthetic_model(base_dir="tests/data/tide_models_synthetic"):
116
116
  lon = np.arange(0, 360.125, 0.125) # 2881 points
117
117
  lat = np.arange(-90, 90.125, 0.125) # 1441 points
118
118
 
119
- # List of hamtide tidal constituents
119
+ # List of HAMTIDE11 tidal constituents
120
120
  constituents = ["2n", "k1", "k2", "m2", "n2", "o1", "p1", "q1", "s2"]
121
121
 
122
- # Create hamtide output directory
122
+ # Create HAMTIDE11 output directory
123
123
  hamtide_dir = base_dir / "hamtide"
124
124
  hamtide_dir.mkdir(parents=True, exist_ok=True)
125
125
 
126
126
  # Create and save a NetCDF for each constituent
127
127
  for constituent in constituents:
128
- # Create synthetic hamtide dataset with random data
128
+ # Create synthetic HAMTIDE11 dataset with random data
129
129
  shape = (len(lat), len(lon)) # 1441, 2881
130
130
  data = np.random.random(shape).astype(np.float32)
131
131
  ds = xr.Dataset(
@@ -142,3 +142,69 @@ def create_synthetic_model(base_dir="tests/data/tide_models_synthetic"):
142
142
  # Export
143
143
  filename = hamtide_dir / f"{constituent}.hamtide11a.nc"
144
144
  ds.to_netcdf(filename)
145
+
146
+
147
+ # Run once per session to generate symethic EOT20 files; autouse=True
148
+ # allows this to run without being specifically called in tests
149
+ @pytest.fixture(scope="session", autouse=True)
150
+ def create_synthetic_eot20(base_dir="tests/data/tide_models_synthetic"):
151
+ """
152
+ Generates and exports synthetic EOT20 model data
153
+ to test clipping functionality.
154
+ """
155
+ base_dir = Path(base_dir) # Ensure base_dir is a Path object
156
+
157
+ # Create coordinate arrays
158
+ lon = np.arange(0, 360.125, 0.125) # 2881 points
159
+ lat = np.arange(-90, 90.125, 0.125) # 1441 points
160
+
161
+ # List of EOT20 tidal constituents
162
+ constituents = [
163
+ "2N2",
164
+ "J1",
165
+ "K1",
166
+ "K2",
167
+ "M2",
168
+ "M4",
169
+ "MF",
170
+ "MM",
171
+ "N2",
172
+ "O1",
173
+ "P1",
174
+ "Q1",
175
+ "S1",
176
+ "S2",
177
+ "SA",
178
+ "SSA",
179
+ "T2",
180
+ ]
181
+
182
+ # Create EOT20 output directory
183
+ eot20_dir = base_dir / "EOT20/ocean_tides"
184
+ eot20_dir.mkdir(parents=True, exist_ok=True)
185
+
186
+ # Create and save a NetCDF for each constituent
187
+ for constituent in constituents:
188
+ # Create synthetic EOT20 dataset with random data
189
+ shape = (len(lat), len(lon)) # 1441, 2881
190
+ data = np.random.random(shape).astype(np.float64)
191
+
192
+ # Add NaN values to match original
193
+ mask = np.random.random(shape) < 0.2
194
+ data[mask] = np.nan
195
+
196
+ # Create the dataset
197
+ ds = xr.Dataset(
198
+ {
199
+ "amplitude": (("lat", "lon"), data),
200
+ "phase": (("lat", "lon"), data),
201
+ "imag": (("lat", "lon"), data),
202
+ "real": (("lat", "lon"), data),
203
+ },
204
+ coords={"lat": lat, "lon": lon},
205
+ attrs={"title": f"DGFI-TUM global empirical ocean tide model"},
206
+ )
207
+
208
+ # Export
209
+ filename = eot20_dir / f"{constituent}_ocean_eot20.nc"
210
+ ds.to_netcdf(filename)
@@ -95,17 +95,21 @@ def test_clip_models():
95
95
  assert np.allclose(df_unclipped.tide_height, df_clipped.tide_height)
96
96
 
97
97
 
98
- # Test clipping across multiple global locations using synthetic HAMTIDE11 data
98
+ # Test clipping across multiple global locations using synthetic tide data
99
99
  @pytest.mark.parametrize(
100
- "bbox, point, name",
100
+ "model, bbox, point, name",
101
101
  [
102
- ((-166, 14, -151, 29), (19.60, -155.46), "hawaii"), # entirely W of prime meridian
103
- ((-13, 49, 6, 60), (51.47, 0.84), "uk"), # crossing prime meridian
104
- ((105, -48, 160, -5), (-25.59, 153.03), "aus"), # entirely E of prime meridian
105
- ((-257, 7, -120, 63), (19.59, -155.45), "pacific"), # crossing antimeridian
102
+ ("EOT20", (-166, 14, -151, 29), (19.60, -155.46), "hawaii"), # entirely W of prime meridian
103
+ ("EOT20", (-13, 49, 6, 60), (51.47, 0.84), "uk"), # crossing prime meridian
104
+ ("EOT20", (105, -48, 160, -5), (-25.59, 153.03), "aus"), # entirely E of prime meridian
105
+ ("EOT20", (-257, 7, -120, 63), (19.59, -155.45), "pacific"), # crossing antimeridian
106
+ ("HAMTIDE11", (-166, 14, -151, 29), (19.60, -155.46), "hawaii"), # entirely W of prime meridian
107
+ ("HAMTIDE11", (-13, 49, 6, 60), (51.47, 0.84), "uk"), # crossing prime meridian
108
+ ("HAMTIDE11", (105, -48, 160, -5), (-25.59, 153.03), "aus"), # entirely E of prime meridian
109
+ ("HAMTIDE11", (-257, 7, -120, 63), (19.59, -155.45), "pacific"), # crossing antimeridian
106
110
  ],
107
111
  )
108
- def test_clip_models_bbox(bbox, point, name):
112
+ def test_clip_models_bbox(model, bbox, point, name):
109
113
  # Set input and output paths
110
114
  in_dir = "tests/data/tide_models_synthetic/"
111
115
  out_dir = f"tests/data/tide_models_synthetic_{name}/"
@@ -115,7 +119,7 @@ def test_clip_models_bbox(bbox, point, name):
115
119
  input_directory=in_dir,
116
120
  output_directory=out_dir,
117
121
  bbox=bbox,
118
- model="HAMTIDE11",
122
+ model=model,
119
123
  overwrite=True,
120
124
  )
121
125
 
@@ -128,14 +132,14 @@ def test_clip_models_bbox(bbox, point, name):
128
132
  x=x,
129
133
  y=y,
130
134
  time=time,
131
- model="HAMTIDE11",
135
+ model=model,
132
136
  directory=in_dir,
133
137
  )
134
138
  df_clipped = model_tides(
135
139
  x=x,
136
140
  y=y,
137
141
  time=time,
138
- model="HAMTIDE11",
142
+ model=model,
139
143
  directory=out_dir,
140
144
  )
141
145
 
@@ -125,52 +125,99 @@
125
125
  " return measured_tides_df.to_xarray()\n",
126
126
  "\n",
127
127
  "\n",
128
- "def create_synthetic_model(base_dir=\"data/tide_models_synthetic\"):\n",
128
+ "def create_synthetic_hamtide11(base_dir=\"tests/data/tide_models_synthetic\"):\n",
129
129
  " \"\"\"\n",
130
130
  " Generates and exports synthetic HAMTIDE11 model data\n",
131
131
  " to test clipping functionality.\n",
132
132
  " \"\"\"\n",
133
133
  " base_dir = Path(base_dir) # Ensure base_dir is a Path object\n",
134
- " \n",
134
+ "\n",
135
135
  " # Create coordinate arrays\n",
136
136
  " lon = np.arange(0, 360.125, 0.125) # 2881 points\n",
137
137
  " lat = np.arange(-90, 90.125, 0.125) # 1441 points\n",
138
- " \n",
139
- " # List of hamtide tidal constituents\n",
140
- " constituents = ['2n', 'k1', 'k2', 'm2', 'n2', 'o1', 'p1', 'q1', 's2']\n",
141
- " \n",
142
- " # Create hamtide output directory\n",
138
+ "\n",
139
+ " # List of HAMTIDE11 tidal constituents\n",
140
+ " constituents = [\"2n\", \"k1\", \"k2\", \"m2\", \"n2\", \"o1\", \"p1\", \"q1\", \"s2\"]\n",
141
+ "\n",
142
+ " # Create HAMTIDE11 output directory\n",
143
143
  " hamtide_dir = base_dir / \"hamtide\"\n",
144
144
  " hamtide_dir.mkdir(parents=True, exist_ok=True)\n",
145
- " \n",
145
+ "\n",
146
146
  " # Create and save a NetCDF for each constituent\n",
147
147
  " for constituent in constituents:\n",
148
148
  "\n",
149
- " # Create synthetic hamtide dataset with random data\n",
149
+ " # Create synthetic HAMTIDE11 dataset with random data\n",
150
150
  " shape = (len(lat), len(lon)) # 1441, 2881\n",
151
151
  " data = np.random.random(shape).astype(np.float32)\n",
152
152
  " ds = xr.Dataset(\n",
153
153
  " {\n",
154
- " 'RE': (('LAT', 'LON'), data),\n",
155
- " 'IM': (('LAT', 'LON'), data),\n",
156
- " 'AMPL': (('LAT', 'LON'), data),\n",
157
- " 'PHAS': (('LAT', 'LON'), data)\n",
154
+ " \"RE\": ((\"LAT\", \"LON\"), data),\n",
155
+ " \"IM\": ((\"LAT\", \"LON\"), data),\n",
156
+ " \"AMPL\": ((\"LAT\", \"LON\"), data),\n",
157
+ " \"PHAS\": ((\"LAT\", \"LON\"), data),\n",
158
158
  " },\n",
159
- " coords={\n",
160
- " 'LON': lon,\n",
161
- " 'LAT': lat\n",
159
+ " coords={\"LON\": lon, \"LAT\": lat},\n",
160
+ " attrs={\"title\": f\"HAMTIDE11a: {constituent} ocean tide\"},\n",
161
+ " )\n",
162
+ "\n",
163
+ " # Export\n",
164
+ " filename = hamtide_dir / f\"{constituent}.hamtide11a.nc\"\n",
165
+ " ds.to_netcdf(filename)\n",
166
+ "\n",
167
+ "\n",
168
+ "def create_synthetic_eot20(base_dir=\"tests/data/tide_models_synthetic\"):\n",
169
+ " \"\"\"\n",
170
+ " Generates and exports synthetic EOT20 model data\n",
171
+ " to test clipping functionality.\n",
172
+ " \"\"\"\n",
173
+ " base_dir = Path(base_dir) # Ensure base_dir is a Path object\n",
174
+ "\n",
175
+ " # Create coordinate arrays\n",
176
+ " lon = np.arange(0, 360.125, 0.125) # 2881 points\n",
177
+ " lat = np.arange(-90, 90.125, 0.125) # 1441 points\n",
178
+ "\n",
179
+ " # List of EOT20 tidal constituents\n",
180
+ " constituents = [\n",
181
+ " \"2N2\", \"J1\", \"K1\", \"K2\", \"M2\", \"M4\", \"MF\", \"MM\", \"N2\",\n",
182
+ " \"O1\", \"P1\", \"Q1\", \"S1\", \"S2\", \"SA\", \"SSA\", \"T2\",\n",
183
+ " ]\n",
184
+ "\n",
185
+ " # Create EOT20 output directory\n",
186
+ " eot20_dir = base_dir / \"EOT20/ocean_tides\"\n",
187
+ " eot20_dir.mkdir(parents=True, exist_ok=True)\n",
188
+ "\n",
189
+ " # Create and save a NetCDF for each constituent\n",
190
+ " for constituent in constituents:\n",
191
+ "\n",
192
+ " # Create synthetic EOT20 dataset with random data\n",
193
+ " shape = (len(lat), len(lon)) # 1441, 2881\n",
194
+ " data = np.random.random(shape).astype(np.float64)\n",
195
+ "\n",
196
+ " # Add NaN values to match original\n",
197
+ " mask = np.random.random(shape) < 0.2\n",
198
+ " data[mask] = np.nan\n",
199
+ "\n",
200
+ " # Create the dataset\n",
201
+ " ds = xr.Dataset(\n",
202
+ " {\n",
203
+ " \"amplitude\": ((\"lat\", \"lon\"), data),\n",
204
+ " \"phase\": ((\"lat\", \"lon\"), data),\n",
205
+ " \"imag\": ((\"lat\", \"lon\"), data),\n",
206
+ " \"real\": ((\"lat\", \"lon\"), data),\n",
162
207
  " },\n",
163
- " attrs={\"title\": f'HAMTIDE11a: {constituent} ocean tide'}\n",
208
+ " coords={\"lat\": lat, \"lon\": lon},\n",
209
+ " attrs={\"title\": f\"DGFI-TUM global empirical ocean tide model\"},\n",
164
210
  " )\n",
165
211
  "\n",
166
212
  " # Export\n",
167
- " filename = hamtide_dir / f'{constituent}.hamtide11a.nc'\n",
213
+ " filename = eot20_dir / f\"{constituent}_ocean_eot20.nc\"\n",
168
214
  " ds.to_netcdf(filename)\n",
169
215
  "\n",
170
216
  "\n",
171
217
  "satellite_ds = load_satellite_ds()\n",
172
218
  "measured_tides_ds = load_measured_tides_ds()\n",
173
- "create_synthetic_model()"
219
+ "create_synthetic_eot20()\n",
220
+ "create_synthetic_hamtide11()"
174
221
  ]
175
222
  },
176
223
  {
@@ -235,7 +282,7 @@
235
282
  },
236
283
  {
237
284
  "cell_type": "code",
238
- "execution_count": 3,
285
+ "execution_count": 5,
239
286
  "metadata": {},
240
287
  "outputs": [
241
288
  {
@@ -248,28 +295,33 @@
248
295
  "rootdir: /home/jovyan/Robbi/eo-tides\n",
249
296
  "configfile: pyproject.toml\n",
250
297
  "plugins: anyio-4.6.2.post1, nbval-0.11.0\n",
251
- "collected 25 items / 20 deselected / 5 selected \u001b[0m\u001b[1m\n",
298
+ "collected 29 items / 20 deselected / 9 selected \u001b[0m\u001b[1m\n",
252
299
  "\n",
253
- "tests/test_utils.py::test_clip_models \u001b[32mPASSED\u001b[0m\u001b[33m [ 20%]\u001b[0m\n",
254
- "tests/test_utils.py::test_clip_models_bbox[bbox0-point0-hawaii] \u001b[32mPASSED\u001b[0m\u001b[33m [ 40%]\u001b[0m\n",
255
- "tests/test_utils.py::test_clip_models_bbox[bbox1-point1-uk] \u001b[32mPASSED\u001b[0m\u001b[33m [ 60%]\u001b[0m\n",
256
- "tests/test_utils.py::test_clip_models_bbox[bbox2-point2-aus] \u001b[32mPASSED\u001b[0m\u001b[33m [ 80%]\u001b[0m\n",
257
- "tests/test_utils.py::test_clip_models_bbox[bbox3-point3-pacific] \u001b[32mPASSED\u001b[0m\u001b[33m [100%]\u001b[0m\n",
300
+ "tests/test_utils.py::test_clip_models \u001b[32mPASSED\u001b[0m\u001b[33m [ 11%]\u001b[0m\n",
301
+ "tests/test_utils.py::test_clip_models_bbox[EOT20-bbox0-point0-hawaii] \u001b[32mPASSED\u001b[0m\u001b[33m [ 22%]\u001b[0m\n",
302
+ "tests/test_utils.py::test_clip_models_bbox[EOT20-bbox1-point1-uk] \u001b[32mPASSED\u001b[0m\u001b[33m [ 33%]\u001b[0m\n",
303
+ "tests/test_utils.py::test_clip_models_bbox[EOT20-bbox2-point2-aus] \u001b[32mPASSED\u001b[0m\u001b[33m [ 44%]\u001b[0m\n",
304
+ "tests/test_utils.py::test_clip_models_bbox[EOT20-bbox3-point3-pacific] \u001b[32mPASSED\u001b[0m\u001b[33m [ 55%]\u001b[0m\n",
305
+ "tests/test_utils.py::test_clip_models_bbox[HAMTIDE11-bbox4-point4-hawaii] \u001b[32mPASSED\u001b[0m\u001b[33m [ 66%]\u001b[0m\n",
306
+ "tests/test_utils.py::test_clip_models_bbox[HAMTIDE11-bbox5-point5-uk] \u001b[32mPASSED\u001b[0m\u001b[33m [ 77%]\u001b[0m\n",
307
+ "tests/test_utils.py::test_clip_models_bbox[HAMTIDE11-bbox6-point6-aus] \u001b[32mPASSED\u001b[0m\u001b[33m [ 88%]\u001b[0m\n",
308
+ "tests/test_utils.py::test_clip_models_bbox[HAMTIDE11-bbox7-point7-pacific] \u001b[32mPASSED\u001b[0m\u001b[33m [100%]\u001b[0m\n",
258
309
  "\n",
259
310
  "\u001b[33m=============================== warnings summary ===============================\u001b[0m\n",
260
311
  "<frozen importlib._bootstrap>:241\n",
261
312
  " <frozen importlib._bootstrap>:241: RuntimeWarning: numpy.ndarray size changed, may indicate binary incompatibility. Expected 16 from C header, got 96 from PyObject\n",
262
313
  "\n",
263
- "tests/test_utils.py: 20 warnings\n",
314
+ "tests/test_utils.py: 36 warnings\n",
264
315
  " /env/lib/python3.10/site-packages/pyproj/transformer.py:817: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)\n",
265
316
  " return self._transformer._transform_point(\n",
266
317
  "\n",
267
- "tests/test_utils.py::test_clip_models_bbox[bbox0-point0-hawaii]\n",
268
- " /home/jovyan/Robbi/eo-tides/eo_tides/model.py:127: UserWarning: On-the-fly cropping is not compatible with the provided clipped model files; running with `crop=False`.\n",
269
- " warnings.warn(\"On-the-fly cropping is not compatible with the provided \"\n",
318
+ "tests/test_utils.py::test_clip_models_bbox[EOT20-bbox0-point0-hawaii]\n",
319
+ "tests/test_utils.py::test_clip_models_bbox[HAMTIDE11-bbox4-point4-hawaii]\n",
320
+ " /home/jovyan/Robbi/eo-tides/eo_tides/model.py:125: UserWarning: On-the-fly cropping is not compatible with the provided clipped model files; running with `crop=False`.\n",
321
+ " warnings.warn(\n",
270
322
  "\n",
271
323
  "-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n",
272
- "\u001b[33m================ \u001b[32m5 passed\u001b[0m, \u001b[33m\u001b[1m20 deselected\u001b[0m, \u001b[33m\u001b[1m22 warnings\u001b[0m\u001b[33m in 16.32s\u001b[0m\u001b[33m ================\u001b[0m\n"
324
+ "\u001b[33m=========== \u001b[32m9 passed\u001b[0m, \u001b[33m\u001b[1m20 deselected\u001b[0m, \u001b[33m\u001b[1m39 warnings\u001b[0m\u001b[33m in 74.74s (0:01:14)\u001b[0m\u001b[33m ===========\u001b[0m\n"
273
325
  ]
274
326
  }
275
327
  ],
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes