|
1 | 1 | {
|
2 | 2 | "cells": [
|
3 | 3 | {
|
| 4 | + "attachments": {}, |
4 | 5 | "cell_type": "markdown",
|
5 | 6 | "metadata": {},
|
6 | 7 | "source": [
|
|
35 | 36 | "- `load_nodal_corrections.py`: load the nodal corrections for tidal constituents \n",
|
36 | 37 | "- `model.py`: retrieves tide model parameters for named tide models\n",
|
37 | 38 | "- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n",
|
38 |
| - "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n", |
| 39 | + "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netCDF4 tide models \n", |
| 40 | + "- `io.GOT.py`: extract tidal harmonic constants from GOT tide models \n", |
39 | 41 | "- `io.FES.py`: extract tidal harmonic constants from FES tide models \n",
|
| 42 | + "- `io.constituents.py`: basic tide model constituent class \n", |
40 | 43 | "- `predict.py`: predict tidal values using harmonic constants \n",
|
41 | 44 | "- `time.py`: utilities for calculating time operations\n",
|
42 | 45 | "- `utilities.py`: download and management utilities for files\n",
|
|
120 | 123 | "metadata": {},
|
121 | 124 | "outputs": [],
|
122 | 125 | "source": [
|
| 126 | + "%matplotlib widget\n", |
| 127 | + "\n", |
123 | 128 | "# get model parameters\n",
|
124 | 129 | "model = pyTMD.model(TMDwidgets.directory.value,\n",
|
125 | 130 | " format=TMDwidgets.atlas.value,\n",
|
|
130 | 135 | "YMD = TMDwidgets.datepick.value\n",
|
131 | 136 | "# calculate a weeks forecast every minute\n",
|
132 | 137 | "minutes = np.arange(7*1440)\n",
|
| 138 | + "# convert time from MJD to days relative to Jan 1, 1992 (48622 MJD)\n", |
133 | 139 | "tide_time = pyTMD.time.convert_calendar_dates(YMD.year, YMD.month,\n",
|
134 | 140 | " YMD.day, minute=minutes)\n",
|
135 | 141 | "hours = minutes/60.0\n",
|
| 142 | + "\n", |
| 143 | + "# create plot with tidal displacements, high and low tides and dates\n", |
| 144 | + "fig,ax1 = plt.subplots(num=1)\n", |
| 145 | + "xmax = np.ceil(hours[-1]).astype('i')\n", |
| 146 | + "l1, = ax1.plot([], [], 'k')\n", |
| 147 | + "l2, = ax1.plot([], [], 'r*')\n", |
| 148 | + "l3, = ax1.plot([], [], 'b*')\n", |
| 149 | + "for h in range(24,xmax,24):\n", |
| 150 | + " ax1.axvline(h,color='gray',lw=0.5,ls='dashed',dashes=(11,5))\n", |
| 151 | + "ax1.set_xlim(0,xmax)\n", |
| 152 | + "ax1.set_ylabel(f'{model.name} Tidal Displacement [cm]')\n", |
| 153 | + "args = (YMD.year,YMD.month,YMD.day)\n", |
| 154 | + "ax1.set_xlabel('Time from {0:4d}-{1:02d}-{2:02d} UTC [Hours]'.format(*args))\n", |
| 155 | + "ttl = ax1.set_title(None)\n", |
| 156 | + "fig.subplots_adjust(left=0.10,right=0.98,bottom=0.10,top=0.95)\n", |
| 157 | + "\n", |
136 | 158 | "# delta time (TT - UT1) file\n",
|
137 | 159 | "delta_file = pyTMD.utilities.get_data_path(['data','merged_deltat.data'])\n",
|
138 | 160 | "\n",
|
139 |
| - "# leaflet location\n", |
140 |
| - "LAT,LON = np.copy(m.marker.location)\n", |
141 |
| - "# verify longitudes\n", |
142 |
| - "LON = m.wrap_longitudes(LON)\n", |
143 | 161 | "# read tidal constants and interpolate to leaflet points\n",
|
144 | 162 | "if model.format in ('OTIS','ATLAS','ESR'):\n",
|
145 |
| - " amp,ph,D,c = pyTMD.io.OTIS.extract_constants(np.atleast_1d(LON),\n", |
146 |
| - " np.atleast_1d(LAT), model.grid_file, model.model_file,\n", |
147 |
| - " model.projection, type=model.type, method='spline',\n", |
148 |
| - " extrapolate=True, grid=model.format)\n", |
| 163 | + " constituents = pyTMD.io.OTIS.read_constants(\n", |
| 164 | + " model.grid_file, model.model_file,\n", |
| 165 | + " model.projection, type=model.type,\n", |
| 166 | + " grid=model.format)\n", |
| 167 | + " c = constituents.fields\n", |
149 | 168 | " DELTAT = np.zeros_like(tide_time)\n",
|
150 | 169 | "elif (model.format == 'netcdf'):\n",
|
151 |
| - " amp,ph,D,c = pyTMD.io.ATLAS.extract_constants(np.atleast_1d(LON),\n", |
152 |
| - " np.atleast_1d(LAT), model.grid_file, model.model_file,\n", |
153 |
| - " type=model.type, method='spline', extrapolate=True,\n", |
154 |
| - " scale=model.scale, compressed=model.compressed)\n", |
| 170 | + " constituents = pyTMD.io.ATLAS.read_constants(\n", |
| 171 | + " model.grid_file, model.model_file,\n", |
| 172 | + " type=model.type, compressed=model.compressed)\n", |
| 173 | + " c = constituents.fields\n", |
155 | 174 | " DELTAT = np.zeros_like(tide_time)\n",
|
156 | 175 | "elif (model.format == 'GOT'):\n",
|
157 |
| - " amp,ph,c = pyTMD.io.GOT.extract_constants(np.atleast_1d(LON),\n", |
158 |
| - " np.atleast_1d(LAT), model.model_file, method='spline',\n", |
159 |
| - " extrapolate=True, scale=model.scale,\n", |
160 |
| - " compressed=model.compressed)\n", |
| 176 | + " constituents = pyTMD.io.GOT.read_constants(\n", |
| 177 | + " model.model_file, compressed=model.compressed)\n", |
| 178 | + " c = constituents.fields\n", |
161 | 179 | " # interpolate delta times from calendar dates to tide time\n",
|
162 | 180 | " DELTAT = pyTMD.time.interpolate_delta_time(delta_file, tide_time)\n",
|
163 | 181 | "elif (model.format == 'FES'):\n",
|
164 |
| - " amp,ph = pyTMD.io.FES.extract_constants(np.atleast_1d(LON),\n", |
165 |
| - " np.atleast_1d(LAT), model.model_file, type=model.type,\n", |
166 |
| - " version=model.version, method='spline', extrapolate=True,\n", |
167 |
| - " scale=model.scale, compressed=model.compressed)\n", |
| 182 | + " constituents = pyTMD.io.FES.read_constants(model.model_file,\n", |
| 183 | + " type=model.type, version=model.version,\n", |
| 184 | + " compressed=model.compressed)\n", |
168 | 185 | " c = model.constituents\n",
|
169 | 186 | " # interpolate delta times from calendar dates to tide time\n",
|
170 | 187 | " DELTAT = pyTMD.time.interpolate_delta_time(delta_file, tide_time)\n",
|
171 | 188 | "\n",
|
172 |
| - "# calculate complex phase in radians for Euler's\n", |
173 |
| - "cph = -1j*ph*np.pi/180.0\n", |
174 |
| - "# calculate constituent oscillation\n", |
175 |
| - "hc = amp*np.exp(cph)\n", |
| 189 | + "# update the tide prediction and plot\n", |
| 190 | + "def update_tide_prediction(*args):\n", |
| 191 | + " # leaflet location\n", |
| 192 | + " LAT,LON = np.copy(m.marker.location)\n", |
| 193 | + " # verify longitudes\n", |
| 194 | + " LON = m.wrap_longitudes(LON)\n", |
| 195 | + " if model.format in ('OTIS','ATLAS','ESR'):\n", |
| 196 | + " amp,ph,D = pyTMD.io.OTIS.interpolate_constants(\n", |
| 197 | + " np.atleast_1d(LON), np.atleast_1d(LAT),\n", |
| 198 | + " constituents, model.projection, type=model.type,\n", |
| 199 | + " method='spline', extrapolate=True)\n", |
| 200 | + " elif (model.format == 'netcdf'):\n", |
| 201 | + " amp,ph,D = pyTMD.io.ATLAS.interpolate_constants(\n", |
| 202 | + " np.atleast_1d(LON), np.atleast_1d(LAT),\n", |
| 203 | + " constituents, type=model.type, scale=model.scale,\n", |
| 204 | + " method='spline', extrapolate=True)\n", |
| 205 | + " elif (model.format == 'GOT'):\n", |
| 206 | + " amp,ph = pyTMD.io.GOT.interpolate_constants(\n", |
| 207 | + " np.atleast_1d(LON), np.atleast_1d(LAT),\n", |
| 208 | + " constituents, scale=model.scale,\n", |
| 209 | + " method='spline', extrapolate=True)\n", |
| 210 | + " elif (model.format == 'FES'):\n", |
| 211 | + " amp,ph = pyTMD.io.FES.interpolate_constants(\n", |
| 212 | + " np.atleast_1d(LON), np.atleast_1d(LAT),\n", |
| 213 | + " constituents, scale=model.scale,\n", |
| 214 | + " method='spline', extrapolate=True)\n", |
| 215 | + " # calculate complex phase in radians for Euler's\n", |
| 216 | + " cph = -1j*ph*np.pi/180.0\n", |
| 217 | + " # calculate constituent oscillation\n", |
| 218 | + " hc = amp*np.exp(cph)\n", |
| 219 | + " # predict tidal elevations at time 1 and infer minor corrections\n", |
| 220 | + " TIDE = pyTMD.predict.time_series(tide_time, hc, c,\n", |
| 221 | + " deltat=DELTAT, corrections=model.format)\n", |
| 222 | + " MINOR = pyTMD.predict.infer_minor(tide_time, hc, c,\n", |
| 223 | + " deltat=DELTAT, corrections=model.format)\n", |
| 224 | + " TIDE.data[:] += MINOR.data[:]\n", |
| 225 | + " # convert to centimeters\n", |
| 226 | + " TIDE.data[:] *= 100.0\n", |
176 | 227 | "\n",
|
177 |
| - "# convert time from MJD to days relative to Jan 1, 1992 (48622 MJD)\n", |
178 |
| - "# predict tidal elevations at time 1 and infer minor corrections\n", |
179 |
| - "TIDE = pyTMD.predict.time_series(tide_time, hc, c,\n", |
180 |
| - " deltat=DELTAT, corrections=model.format)\n", |
181 |
| - "MINOR = pyTMD.predict.infer_minor(tide_time, hc, c,\n", |
182 |
| - " deltat=DELTAT, corrections=model.format)\n", |
183 |
| - "TIDE.data[:] += MINOR.data[:]\n", |
184 |
| - "# convert to centimeters\n", |
185 |
| - "TIDE.data[:] *= 100.0\n", |
186 |
| - "\n", |
187 |
| - "# differentiate to calculate high and low tides\n", |
188 |
| - "diff = np.zeros_like(tide_time, dtype=np.float64)\n", |
189 |
| - "# forward differentiation for starting point\n", |
190 |
| - "diff[0] = TIDE.data[1] - TIDE.data[0]\n", |
191 |
| - "# backward differentiation for end point\n", |
192 |
| - "diff[-1] = TIDE.data[-1] - TIDE.data[-2]\n", |
193 |
| - "# centered differentiation for all others\n", |
194 |
| - "diff[1:-1] = (TIDE.data[2:] - TIDE.data[0:-2])/2.0\n", |
195 |
| - "# indices of high and low tides\n", |
196 |
| - "htindex, = np.nonzero((np.sign(diff[0:-1]) >= 0) & (np.sign(diff[1:]) < 0))\n", |
197 |
| - "ltindex, = np.nonzero((np.sign(diff[0:-1]) <= 0) & (np.sign(diff[1:]) > 0))\n", |
| 228 | + " # differentiate to calculate high and low tides\n", |
| 229 | + " diff = np.zeros_like(tide_time, dtype=np.float64)\n", |
| 230 | + " # forward differentiation for starting point\n", |
| 231 | + " diff[0] = TIDE.data[1] - TIDE.data[0]\n", |
| 232 | + " # backward differentiation for end point\n", |
| 233 | + " diff[-1] = TIDE.data[-1] - TIDE.data[-2]\n", |
| 234 | + " # centered differentiation for all others\n", |
| 235 | + " diff[1:-1] = (TIDE.data[2:] - TIDE.data[0:-2])/2.0\n", |
| 236 | + " # indices of high and low tides\n", |
| 237 | + " htindex, = np.nonzero((np.sign(diff[0:-1]) >= 0) & (np.sign(diff[1:]) < 0))\n", |
| 238 | + " ltindex, = np.nonzero((np.sign(diff[0:-1]) <= 0) & (np.sign(diff[1:]) > 0))\n", |
| 239 | + " # update plot data\n", |
| 240 | + " l1.set_data(hours, TIDE.data)\n", |
| 241 | + " l2.set_data(hours[htindex], TIDE.data[htindex])\n", |
| 242 | + " l3.set_data(hours[ltindex], TIDE.data[ltindex])\n", |
| 243 | + " # update plot title\n", |
| 244 | + " ttl.set_text(u'{0:0.6f}\\u00b0N {1:0.6f}\\u00b0W'.format(LAT,LON))\n", |
| 245 | + " ax1.relim()\n", |
| 246 | + " ax1.autoscale_view()\n", |
| 247 | + " fig.canvas.draw()\n", |
198 | 248 | "\n",
|
199 |
| - "# create plot with tidal displacements, high and low tides and dates\n", |
200 |
| - "fig,ax1 = plt.subplots(num=1)\n", |
201 |
| - "xmax = np.ceil(hours[-1]).astype('i')\n", |
202 |
| - "ax1.plot(hours, TIDE.data, 'k')\n", |
203 |
| - "ax1.plot(hours[htindex], TIDE.data[htindex], 'r*')\n", |
204 |
| - "ax1.plot(hours[ltindex], TIDE.data[ltindex], 'b*')\n", |
205 |
| - "for h in range(24,xmax,24):\n", |
206 |
| - " ax1.axvline(h,color='gray',lw=0.5,ls='dashed',dashes=(11,5))\n", |
207 |
| - "ax1.set_xlim(0,xmax)\n", |
208 |
| - "ax1.set_ylabel(f'{model.name} Tidal Displacement [cm]')\n", |
209 |
| - "args = (YMD.year,YMD.month,YMD.day)\n", |
210 |
| - "ax1.set_xlabel('Time from {0:4d}-{1:02d}-{2:02d} UTC [Hours]'.format(*args))\n", |
211 |
| - "ax1.set_title(u'{0:0.6f}\\u00b0N {1:0.6f}\\u00b0W'.format(LAT,LON))\n", |
212 |
| - "fig.subplots_adjust(left=0.10,right=0.98,bottom=0.10,top=0.95)" |
| 249 | + "# run tide prediction at initial location\n", |
| 250 | + "update_tide_prediction()\n", |
| 251 | + "# watch marker location for changes\n", |
| 252 | + "m.marker_text.observe(update_tide_prediction)" |
213 | 253 | ]
|
214 |
| - }, |
215 |
| - { |
216 |
| - "cell_type": "code", |
217 |
| - "execution_count": null, |
218 |
| - "metadata": {}, |
219 |
| - "outputs": [], |
220 |
| - "source": [] |
221 | 254 | }
|
222 | 255 | ],
|
223 | 256 | "metadata": {
|
|
0 commit comments