From da01d659269528c600c61484baeb1649b42fbbca Mon Sep 17 00:00:00 2001 From: tsutterley Date: Thu, 7 Nov 2024 12:43:52 -0800 Subject: [PATCH] add Byun-Hart class --- .../notebooks/Plot-Tide-Form-Factor.ipynb | 89 +++++++++++++++---- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/doc/source/notebooks/Plot-Tide-Form-Factor.ipynb b/doc/source/notebooks/Plot-Tide-Form-Factor.ipynb index 8aadc759..4f784280 100644 --- a/doc/source/notebooks/Plot-Tide-Form-Factor.ipynb +++ b/doc/source/notebooks/Plot-Tide-Form-Factor.ipynb @@ -8,7 +8,10 @@ "Plot Tide Form Factor\n", "======================\n", "\n", - "This ({nb-download}`notebook `) demonstrates plotting daily tidal form factors for determining the dominant species of a region using the classifications from [Courtier (1938)](https://journals.lib.unb.ca/index.php/ihr/article/download/27428/1882520184). The dominant species classifications do have limitations as pointed out by [Amin (1986)](https://journals.lib.unb.ca/index.php/ihr/article/download/23443/27218/0).\n", + "This ({nb-download}`notebook `) demonstrates plotting tidal form factors for classifying tides\n", + "\n", + "- Daily tidal form factors for determining the dominant species of a region using the classifications from [Courtier (1938)](https://journals.lib.unb.ca/index.php/ihr/article/download/27428/1882520184). The dominant species classifications do have limitations as pointed out by [Amin (1986)](https://journals.lib.unb.ca/index.php/ihr/article/download/23443/27218/0)\n", + "- Monthly tidal form factors for semi-diurnal species from [Byun and Hart](https://doi.org/10.5194/os-16-965-2020)\n", "\n", "OTIS format tidal solutions provided by Oregon State University and ESR \n", "- [http://volkov.oce.orst.edu/tides/region.html](http://volkov.oce.orst.edu/tides/region.html) \n", @@ -60,6 +63,7 @@ "import matplotlib.pyplot as plt\n", "import matplotlib.colors as colors\n", "import cartopy.crs as ccrs\n", + "import ipywidgets\n", "\n", "# import tide programs\n", "import pyTMD.io\n", @@ -150,14 +154,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Calculate tidal form factors\n", - "\n", - "Calculate the ratios between major diurnal tides and major semi-diurnal tides\n", - "\n", - "- F: < 0.25: Semi-diurnal\n", - "- F: 0.25 - 1.5: Mixed predominantly semi-diurnal\n", - "- F: 1.5 - 3.0: Mixed predominantly diurnal\n", - "- F: > 3.0: Diurnal" + "## Calculate tidal amplitudes and phases" ] }, { @@ -183,15 +180,75 @@ " amp,ph = pyTMD.io.FES.extract_constants(lon, lat, model.model_file,\n", " type=model.type, version=model.version, crop=True,\n", " method='spline', scale=model.scale, compressed=model.compressed)\n", - " c = model.constituents\n", + " c = model.constituents" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Calculate tidal form factors\n", + "\n", + "Courtier form factor:\n", + "Ratios between major diurnal tides and major semi-diurnal tides\n", + "\n", + "- F: < 0.25: Semi-diurnal\n", + "- F: 0.25 - 1.5: Mixed predominantly semi-diurnal\n", + "- F: 1.5 - 3.0: Mixed predominantly diurnal\n", + "- F: > 3.0: Diurnal\n", + "\n", + "Byut-Hart form factor:\n", + "Ratios between semi-diurnal tides for monthly tidal envelopes\n", "\n", + "- E: < 0.8: Spring-Neap\n", + "- E: 0.8 - 1.0: Mixed predominantly Spring-Neap\n", + "- E: 1.0 - 1.15: Mixed predominantly Perigean-Apogean\n", + "- E: > 2.0: Perigean-Apogean\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "TMDwidgets.form_factor = ipywidgets.Dropdown(\n", + " options=['Courtier','Byun-Hart'],\n", + " value='Courtier',\n", + " description='Factor:',\n", + " disabled=False,\n", + " style=TMDwidgets.style,\n", + ")\n", + "display(TMDwidgets.form_factor)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "# find constituents for tidal form factors\n", "k1 = c.index('k1')\n", "o1 = c.index('o1')\n", "m2 = c.index('m2')\n", "s2 = c.index('s2')\n", - "# tidal form factor from Courtier\n", - "F = np.reshape((amp[:,k1] + amp[:,o1])/(amp[:,m2] + amp[:,s2]), (ny,nx))" + "n2 = c.index('n2')\n", + "# select form factor\n", + "if TMDwidgets.form_factor.value == 'Courtier':\n", + " # tidal form factor from Courtier\n", + " factor = np.reshape((amp[:,k1] + amp[:,o1])/(amp[:,m2] + amp[:,s2]), (ny,nx))\n", + " boundary = np.array([0.0, 0.25, 1.5, 3.0, 5.0])\n", + " ticklabels = ['Semi-Diurnal', 'Mixed SD', 'Mixed D', 'Diurnal']\n", + " longname = 'Tide Species Classification'\n", + "elif TMDwidgets.form_factor.value == 'Byun-Hart':\n", + " # semi-diurnal form factor from Byun and Hart\n", + " factor = np.reshape((amp[:,m2] + amp[:,n2])/(amp[:,m2] + amp[:,s2]), (ny,nx))\n", + " boundary = np.array([0.0, 0.8, 1.0, 1.15, 2.0])\n", + " ticklabels = ['Spring-Neap', 'Mixed S-N', 'Mixed P-A', 'Perigean-Apogean']\n", + " longname = 'Semi-Diurnal Classification'\n", + "# calculate ticks for labels\n", + "ticks = 0.5*(boundary[1:] + boundary[:-1])" ] }, { @@ -213,12 +270,10 @@ "fig, ax = plt.subplots(num=1, figsize=(5.5,3.5),\n", " subplot_kw=dict(projection=projection))\n", "# create boundary norm\n", - "boundary = [0.0, 0.25, 1.5, 3.0, 5.0]\n", - "ticklabels = ['Semi-Diurnal', 'Mixed SD', 'Mixed D', 'Diurnal']\n", "norm = colors.BoundaryNorm(boundary, ncolors=256)\n", "# plot tidal form factor\n", "extent = (xlimits[0],xlimits[1],ylimits[0],ylimits[1])\n", - "im = ax.imshow(F, interpolation='nearest',\n", + "im = ax.imshow(factor, interpolation='nearest',\n", " norm=norm, cmap='plasma', transform=projection,\n", " extent=extent, origin='lower')\n", "# add high resolution cartopy coastlines\n", @@ -236,10 +291,10 @@ "# rasterized colorbar to remove lines\n", "cbar.solids.set_rasterized(True)\n", "# Add label to the colorbar\n", - "cbar.ax.set_title('Tide Species Category', fontsize=13,\n", + "cbar.ax.set_title(longname, fontsize=13,\n", " rotation=0, y=-2.0, va='top')\n", "# Set the tick levels for the colorbar\n", - "cbar.set_ticks(ticks=[0.125, 0.875, 2.25, 4], labels=ticklabels)\n", + "cbar.set_ticks(ticks=ticks, labels=ticklabels)\n", "\n", "# axis = equal\n", "ax.set_aspect('equal', adjustable='box')\n",