Plot Tide Forecasts

This notebook demonstrates plotting a weekly forecast of tidal displacements at a given location

Important

Need to download tide model prior to running this notebook.

OTIS format tidal solutions provided by Oregon State University and ESR

Global Tide Model (GOT) solutions provided by Richard Ray at GSFC

Finite Element Solution (FES) provided by AVISO

Python Dependencies

Program Dependencies

  • astro.py: computes the basic astronomical mean longitudes

  • constituents.py: calculates constituent parameters and nodal arguments

  • io.model.py: retrieves tide model parameters for named tide models

  • io.OTIS.py: extract tidal harmonic constants from OTIS tide models

  • io.ATLAS.py: extract tidal harmonic constants from ATLAS netCDF4 tide models

  • io.GOT.py: extract tidal harmonic constants from GOT tide models

  • io.FES.py: extract tidal harmonic constants from FES tide models

  • predict.py: predict tidal values using harmonic constants

Note

This notebook uses Jupyter widgets to set parameters for calculating the tidal forecasts.

Load modules

from __future__ import print_function

import numpy as np
import matplotlib.pyplot as plt
import IPython.display

# import tide programs
import pyTMD.io
import pyTMD.predict
import pyTMD.tools
import timescale.time

# autoreload
%load_ext autoreload
%autoreload 2

Set parameters for program

  • Model directory

  • Tide model

  • Date to run

# available model list
model_list = sorted(pyTMD.io.model.ocean_elevation())
# display widgets for setting directory and model
TMDwidgets = pyTMD.tools.widgets()
TMDwidgets.model.options = model_list
TMDwidgets.model.value = "GOT4.10_nc"
TMDwidgets.VBox([TMDwidgets.directory, TMDwidgets.model])

Open tide model dataset

# get model parameters
model = pyTMD.io.model(TMDwidgets.directory.value).from_database(
    TMDwidgets.model.value
)
ds = model.open_dataset(group="z", chunks="auto")

Create leaflet map for select location for tide forecast

%matplotlib widget
# calculate a weeks forecast every minute
minutes = np.arange(7 * 1440)
hours = minutes / 60.0

# create leaflet map
m = pyTMD.tools.leaflet(
    center=(45.00, -65.75),
    zoom=7,
    zoom_control=True,
    marker_control=True,
    attribution=False,
)

# create plot with tidal displacements, high and low tides and dates
fig, ax1 = plt.subplots(num=1)
xmax = np.ceil(hours[-1]).astype("i")
(l1,) = ax1.plot([], [], "k")
(l2,) = ax1.plot([], [], "r*")
(l3,) = ax1.plot([], [], "b*")
for h in range(24, xmax, 24):
    ax1.axvline(h, color="gray", lw=0.5, ls="dashed", dashes=(11, 5))
ax1.set_xlim(0, xmax)
ax1.set_ylabel(f"{model.name} Tidal Displacement [cm]")
axlabel = ax1.set_xlabel(None)
ttl = ax1.set_title(None)
fig.subplots_adjust(left=0.11, right=0.98, bottom=0.10, top=0.95)


# update the tide prediction and plot
def update_tide_prediction(*args):
    # convert from calendar date to days relative to Jan 1, 1992 (48622 MJD)
    YMD = TMDwidgets.datepick.value
    # convert time from MJD to days relative to Jan 1, 1992 (48622 MJD)
    ts = timescale.from_calendar(YMD.year, YMD.month, YMD.day, minute=minutes)
    # delta time (TT - UT1)
    if model.corrections in ("OTIS", "ATLAS", "TMD3"):
        deltat = np.zeros_like(ts.tide)
    else:
        deltat = ts.tt_ut1
    # leaflet location
    latitude, longitude = np.copy(m.marker.location)
    # verify longitudes
    longitude = m.wrap_longitudes(longitude)
    # convert to model grid coordinates
    x, y = ds.tmd.coords_as(longitude, latitude)
    # interpolate to grid points and convert to centimeters
    local = ds.tmd.interp(x, y, extrapolate=True)
    local = local.tmd.to_units("cm")
    # predict tidal elevations at time
    tpred = local.tmd.predict(
        ts.tide, deltat=deltat, corrections=model.corrections
    )
    # infer minor constituents and add to major components
    tpred += local.tmd.infer(
        ts.tide, deltat=deltat, corrections=model.corrections
    )
    # differentiate to calculate high and low tides
    high_peaks, low_peaks = tpred.tmd.find_peaks()
    # update plot data
    l1.set_data(hours, tpred.values)
    l2.set_data(hours[high_peaks], tpred.values[high_peaks])
    l3.set_data(hours[low_peaks], tpred.values[low_peaks])
    # update x label for dates
    txt = f"Time from {YMD.year:4d}-{YMD.month:02d}-{YMD.day:02d} UTC [Hours]"
    axlabel.set_text(txt)
    # update plot title
    ttl.set_text("{0:0.6f}\u00b0N {1:0.6f}\u00b0E".format(latitude, longitude))
    ax1.relim()
    ax1.autoscale_view()
    fig.canvas.draw()


# run tide prediction at initial location
update_tide_prediction()
# watch marker location for changes
m.marker_text.observe(update_tide_prediction)
# update tide predictions for date range change
TMDwidgets.datepick.observe(update_tide_prediction)
# show map
TMDwidgets.VBox([m.map, TMDwidgets.datepick])