diff --git a/doc/source/api_reference/check_tide_points.rst b/doc/source/api_reference/check_points.rst similarity index 61% rename from doc/source/api_reference/check_tide_points.rst rename to doc/source/api_reference/check_points.rst index 38786b7b..d7c57b91 100644 --- a/doc/source/api_reference/check_tide_points.rst +++ b/doc/source/api_reference/check_points.rst @@ -1,6 +1,6 @@ -================= -check_tide_points -================= +============ +check_points +============ - Check if points are within a tide model domain - Can check OTIS format tidal solutions provided by Ohio State University and ESR @@ -12,12 +12,11 @@ Calling Sequence .. code-block:: python - from pyTMD.check_tide_points import check_tide_points - valid = check_tide_points(x, y, DIRECTORY=DIRECTORY, - MODEL=MODEL, EPSG=3031) + import pyTMD + valid = pyTMD.check_points(x, y, DIRECTORY=DIRECTORY, MODEL=MODEL, EPSG=3031) `Source code`__ -.. __: https://github.com/tsutterley/pyTMD/blob/main/pyTMD/check_tide_points.py +.. __: https://github.com/tsutterley/pyTMD/blob/main/pyTMD/check_points.py -.. autofunction:: pyTMD.check_tide_points +.. autofunction:: pyTMD.check_points diff --git a/doc/source/api_reference/compute_tide_corrections.rst b/doc/source/api_reference/compute_tide_corrections.rst index 7533d445..438f3250 100644 --- a/doc/source/api_reference/compute_tide_corrections.rst +++ b/doc/source/api_reference/compute_tide_corrections.rst @@ -19,9 +19,10 @@ Calling Sequence .. code-block:: python - from pyTMD.compute_tide_corrections import compute_tide_corrections - tide = compute_tide_corrections(x, y, delta_time, DIRECTORY=DIRECTORY, - MODEL=MODEL, EPOCH=(2000,1,1,0,0,0), EPSG=3031, TYPE='drift') + import pyTMD + tide = pyTMD.compute_tide_corrections(x, y, delta_time, + DIRECTORY=DIRECTORY, MODEL=MODEL, EPOCH=(2000,1,1,0,0,0), + EPSG=3031, TYPE='drift') `Source code`__ diff --git a/doc/source/api_reference/tidal_ellipse.rst b/doc/source/api_reference/ellipse.rst similarity index 52% rename from doc/source/api_reference/tidal_ellipse.rst rename to doc/source/api_reference/ellipse.rst index 9358b2b5..80e566f5 100644 --- a/doc/source/api_reference/tidal_ellipse.rst +++ b/doc/source/api_reference/ellipse.rst @@ -1,6 +1,6 @@ -============= -tidal_ellipse -============= +======= +ellipse +======= - Expresses the amplitudes and phases for the `u` and `v` components in terms of four ellipse parameters using `Foreman's formula `_ @@ -9,11 +9,11 @@ Calling Sequence .. code-block:: python - from pyTMD.tidal_ellipse import tidal_ellipse - umajor,uminor,uincl,uphase = tidal_ellipse(u,v) + import pyTMD + umajor,uminor,uincl,uphase = pyTMD.ellipse(u,v) `Source code`__ -.. __: https://github.com/tsutterley/pyTMD/blob/main/pyTMD/tidal_ellipse.py +.. __: https://github.com/tsutterley/pyTMD/blob/main/pyTMD/ellipse.py -.. autofunction:: pyTMD.tidal_ellipse +.. autofunction:: pyTMD.ellipse diff --git a/doc/source/api_reference/load_constituent.rst b/doc/source/api_reference/load_constituent.rst deleted file mode 100644 index 2610d758..00000000 --- a/doc/source/api_reference/load_constituent.rst +++ /dev/null @@ -1,19 +0,0 @@ -================ -load_constituent -================ - -- Loads parameters for a given tidal constituent - -Calling Sequence ----------------- - -.. code-block:: python - - from pyTMD.load_constituent import load_constituent - amplitude,phase,omega,alpha,species = load_constituent(c) - -`Source code`__ - -.. __: https://github.com/tsutterley/pyTMD/blob/main/pyTMD/load_constituent.py - -.. autofunction:: pyTMD.load_constituent diff --git a/doc/source/api_reference/predict.rst b/doc/source/api_reference/predict.rst index aabb32e9..0a0638fb 100644 --- a/doc/source/api_reference/predict.rst +++ b/doc/source/api_reference/predict.rst @@ -36,6 +36,8 @@ Calling Sequence .. autofunction:: pyTMD.predict.solid_earth_tide +.. autofunction:: pyTMD.predict._constituent_parameters + .. autofunction:: pyTMD.predict._out_of_phase_diurnal .. autofunction:: pyTMD.predict._out_of_phase_semidiurnal diff --git a/doc/source/index.rst b/doc/source/index.rst index a1d1d091..48a1f9ac 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -31,10 +31,11 @@ ocean, load, solid Earth and pole tides api_reference/arguments.rst api_reference/astro.rst - api_reference/check_tide_points.rst + api_reference/check_points.rst api_reference/compute_tide_corrections.rst api_reference/constants.rst api_reference/convert_crs.rst + api_reference/ellipse.rst api_reference/eop.rst api_reference/interpolate.rst api_reference/io/ATLAS.rst @@ -44,10 +45,8 @@ ocean, load, solid Earth and pole tides api_reference/io/constituents.rst api_reference/io/model.rst api_reference/io/ocean_pole_tide.rst - api_reference/load_constituent.rst api_reference/predict.rst api_reference/spatial.rst - api_reference/tidal_ellipse.rst api_reference/time.rst api_reference/utilities.rst diff --git a/notebooks/Plot Antarctic Tidal Currents.ipynb b/notebooks/Plot Antarctic Tidal Currents.ipynb index ffd855bb..e47c67a8 100644 --- a/notebooks/Plot Antarctic Tidal Currents.ipynb +++ b/notebooks/Plot Antarctic Tidal Currents.ipynb @@ -31,7 +31,6 @@ "- `arguments.py`: load the nodal corrections for tidal constituents \n", "- `astro.py`: computes the basic astronomical mean longitudes \n", "- `convert_crs.py`: convert points to and from Coordinates Reference Systems \n", - "- `load_constituent.py`: loads parameters for a given tidal constituent \n", "- `io.model.py`: retrieves tide model parameters for named tide models\n", "- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n", "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n", diff --git a/notebooks/Plot Arctic Ocean Map.ipynb b/notebooks/Plot Arctic Ocean Map.ipynb index 029af20f..b14d2aa3 100644 --- a/notebooks/Plot Arctic Ocean Map.ipynb +++ b/notebooks/Plot Arctic Ocean Map.ipynb @@ -33,7 +33,6 @@ "- `arguments.py`: load the nodal corrections for tidal constituents \n", "- `astro.py`: computes the basic astronomical mean longitudes \n", "- `convert_crs.py`: convert points to and from Coordinates Reference Systems \n", - "- `load_constituent.py`: loads parameters for a given tidal constituent \n", "- `io.model.py`: retrieves tide model parameters for named tide models \n", "- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n", "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n", diff --git a/notebooks/Plot Ross Ice Shelf Map.ipynb b/notebooks/Plot Ross Ice Shelf Map.ipynb index 8b6f2663..914b9a82 100644 --- a/notebooks/Plot Ross Ice Shelf Map.ipynb +++ b/notebooks/Plot Ross Ice Shelf Map.ipynb @@ -33,7 +33,6 @@ "- `arguments.py`: load the nodal corrections for tidal constituents \n", "- `astro.py`: computes the basic astronomical mean longitudes \n", "- `convert_crs.py`: convert points to and from Coordinates Reference Systems \n", - "- `load_constituent.py`: loads parameters for a given tidal constituent \n", "- `io.model.py`: retrieves tide model parameters for named tide models\n", "- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n", "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netcdf models \n", diff --git a/notebooks/Plot Tide Forecasts.ipynb b/notebooks/Plot Tide Forecasts.ipynb index 347acd59..e2f927ad 100644 --- a/notebooks/Plot Tide Forecasts.ipynb +++ b/notebooks/Plot Tide Forecasts.ipynb @@ -33,7 +33,6 @@ "- `arguments.py`: load the nodal corrections for tidal constituents \n", "- `astro.py`: computes the basic astronomical mean longitudes \n", "- `convert_crs.py`: convert points to and from Coordinates Reference Systems \n", - "- `load_constituent.py`: loads parameters for a given tidal constituent \n", "- `io.model.py`: retrieves tide model parameters for named tide models\n", "- `io.OTIS.py`: extract tidal harmonic constants from OTIS tide models \n", "- `io.ATLAS.py`: extract tidal harmonic constants from ATLAS netCDF4 tide models \n", diff --git a/pyTMD/__init__.py b/pyTMD/__init__.py index 07306fe7..c6185e02 100644 --- a/pyTMD/__init__.py +++ b/pyTMD/__init__.py @@ -22,7 +22,7 @@ import pyTMD.version from pyTMD import io from pyTMD.arguments import arguments -from pyTMD.check_tide_points import check_tide_points +from pyTMD.check_points import check_points from pyTMD.compute_tide_corrections import ( compute_corrections, compute_tide_corrections, @@ -36,8 +36,7 @@ _ellipsoids ) from pyTMD.convert_crs import convert_crs -from pyTMD.load_constituent import load_constituent -from pyTMD.tidal_ellipse import tidal_ellipse +from pyTMD.ellipse import ellipse # Deprecated functions from pyTMD.calc_astrol_longitudes import calc_astrol_longitudes diff --git a/pyTMD/check_tide_points.py b/pyTMD/check_points.py similarity index 99% rename from pyTMD/check_tide_points.py rename to pyTMD/check_points.py index 29f34beb..c8d5843e 100644 --- a/pyTMD/check_tide_points.py +++ b/pyTMD/check_points.py @@ -1,6 +1,6 @@ #!/usr/bin/env python u""" -check_tide_points.py +check_points.py Written by Tyler Sutterley (04/2023) Check if points are within a tide model domain @@ -86,7 +86,7 @@ logging.debug("pyproj not available") # PURPOSE: compute tides at points and times using tide model algorithms -def check_tide_points(x: np.ndarray, y: np.ndarray, +def check_points(x: np.ndarray, y: np.ndarray, DIRECTORY: str | pathlib.Path | None = None, MODEL: str | None = None, ATLAS_FORMAT: str = 'netcdf', diff --git a/pyTMD/compute_tide_corrections.py b/pyTMD/compute_tide_corrections.py index ea87e849..6ab7006f 100644 --- a/pyTMD/compute_tide_corrections.py +++ b/pyTMD/compute_tide_corrections.py @@ -50,7 +50,6 @@ arguments.py: load the nodal corrections for tidal constituents astro.py: computes the basic astronomical mean longitudes convert_crs.py: convert points to and from Coordinates Reference Systems - load_constituent.py: loads parameters for a given tidal constituent predict.py: predict tide values using harmonic constants io/model.py: retrieves tide model parameters for named tide models io/OTIS.py: extract tidal harmonic constants from OTIS tide models diff --git a/pyTMD/tidal_ellipse.py b/pyTMD/ellipse.py similarity index 94% rename from pyTMD/tidal_ellipse.py rename to pyTMD/ellipse.py index 688a501f..86ffed92 100644 --- a/pyTMD/tidal_ellipse.py +++ b/pyTMD/ellipse.py @@ -1,11 +1,11 @@ #!/usr/bin/env python u""" -tidal_ellipse.py (03/2023) +ellipse.py (03/2023) Expresses the amplitudes and phases for the u and v components in terms of four ellipse parameters using Foreman's formula CALLING SEQUENCE: - umajor,uminor,uincl,uphase = tidal_ellipse(u,v) + umajor,uminor,uincl,uphase = ellipse(u,v) INPUTS: u: zonal current (EW) @@ -24,6 +24,7 @@ https://doi.org/10.1016/0309-1708(89)90017-1 UPDATE HISTORY: + Updated 09/2023: renamed to ellipse.py (from tidal_ellipse.py) Updated 03/2023: add basic variable typing to function inputs Updated 04/2022: updated docstrings to numpy documentation format Written 07/2020 @@ -32,7 +33,7 @@ import numpy as np -def tidal_ellipse(u: np.ndarray, v: np.ndarray): +def ellipse(u: np.ndarray, v: np.ndarray): """ Expresses the amplitudes and phases for the u and v components in terms of four ellipse parameters using Foreman's formula [1]_ diff --git a/pyTMD/interpolate.py b/pyTMD/interpolate.py index e6b9bab9..c54a3992 100644 --- a/pyTMD/interpolate.py +++ b/pyTMD/interpolate.py @@ -107,7 +107,6 @@ def bilinear( # return interpolated values return data - def spline( ilon: np.ndarray, ilat: np.ndarray, diff --git a/pyTMD/io/ATLAS.py b/pyTMD/io/ATLAS.py index 5ffedfd8..ba95322f 100644 --- a/pyTMD/io/ATLAS.py +++ b/pyTMD/io/ATLAS.py @@ -911,11 +911,11 @@ def output_netcdf_grid( nc['lat_u'] = fileID.createVariable('lat_u', lat_u.dtype, ('ny',)) nc['lon_v'] = fileID.createVariable('lon_v', lon_v.dtype, ('nx',)) nc['lat_v'] = fileID.createVariable('lat_v', lat_v.dtype, ('ny',)) - nc['hz'] = fileID.createVariable('hz', hz.dtype, ('ny','nx',), + nc['hz'] = fileID.createVariable('hz', hz.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['hu'] = fileID.createVariable('hu', hu.dtype, ('ny','nx',), + nc['hu'] = fileID.createVariable('hu', hu.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['hv'] = fileID.createVariable('hv', hv.dtype, ('ny','nx',), + nc['hv'] = fileID.createVariable('hv', hv.dtype, ('nx','ny',), fill_value=0, zlib=True) # filling the NetCDF variables nc['lon_z'][:] = lon_z[:] @@ -924,9 +924,9 @@ def output_netcdf_grid( nc['lat_u'][:] = lat_u[:] nc['lon_v'][:] = lon_v[:] nc['lat_v'][:] = lat_v[:] - nc['hz'][:] = hz[:] - nc['hu'][:] = hu[:] - nc['hv'][:] = hv[:] + nc['hz'][:] = hz[:].T + nc['hu'][:] = hu[:].T + nc['hv'][:] = hv[:].T # define variable attributes for TYPE in ('z','u','v'): # set variable attributes for coordinates @@ -992,15 +992,15 @@ def output_netcdf_elevation( nc = {} nc['lon_z'] = fileID.createVariable('lon_z', lon_z.dtype, ('nx',)) nc['lat_z'] = fileID.createVariable('lat_z', lat_z.dtype, ('ny',)) - nc['hRe'] = fileID.createVariable('hRe', h.real.dtype, ('ny','nx',), + nc['hRe'] = fileID.createVariable('hRe', h.real.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['hIm'] = fileID.createVariable('hIm', h.imag.dtype, ('ny','nx',), + nc['hIm'] = fileID.createVariable('hIm', h.imag.dtype, ('nx','ny',), fill_value=0, zlib=True) # filling the NetCDF variables nc['lon_z'][:] = lon_z[:] nc['lat_z'][:] = lat_z[:] - nc['hRe'][:] = h.real[:] - nc['hIm'][:] = h.imag[:] + nc['hRe'][:] = h.real[:].T + nc['hIm'][:] = h.imag[:].T # define variable attributes complexpart = dict(Re='Real part', Im='Imag part') # set variable attributes for coordinates @@ -1087,23 +1087,23 @@ def output_netcdf_transport( nc['lat_u'] = fileID.createVariable('lat_u', lat_u.dtype, ('ny',)) nc['lon_v'] = fileID.createVariable('lon_v', lon_v.dtype, ('nx',)) nc['lat_v'] = fileID.createVariable('lat_v', lat_v.dtype, ('ny',)) - nc['uRe'] = fileID.createVariable('uRe', u.real.dtype, ('ny','nx',), + nc['uRe'] = fileID.createVariable('uRe', u.real.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['uIm'] = fileID.createVariable('uIm', u.imag.dtype, ('ny','nx',), + nc['uIm'] = fileID.createVariable('uIm', u.imag.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['vRe'] = fileID.createVariable('vRe', v.real.dtype, ('ny','nx',), + nc['vRe'] = fileID.createVariable('vRe', v.real.dtype, ('nx','ny',), fill_value=0, zlib=True) - nc['vIm'] = fileID.createVariable('vIm', v.imag.dtype, ('ny','nx',), + nc['vIm'] = fileID.createVariable('vIm', v.imag.dtype, ('nx','ny',), fill_value=0, zlib=True) # filling the NetCDF variables nc['lon_u'][:] = lon_u[:] nc['lat_u'][:] = lat_u[:] nc['lon_v'][:] = lon_v[:] nc['lat_v'][:] = lat_v[:] - nc['uRe'][:] = u.real[:] - nc['uIm'][:] = u.imag[:] - nc['vRe'][:] = v.real[:] - nc['vIm'][:] = v.imag[:] + nc['uRe'][:] = u.real[:].T + nc['uIm'][:] = u.imag[:].T + nc['vRe'][:] = v.real[:].T + nc['vIm'][:] = v.imag[:].T # define variable attributes direction = dict(u='WE', v='SN') complexpart = dict(Re='Real part', Im='Imag part') diff --git a/pyTMD/io/model.py b/pyTMD/io/model.py index 9d79d6dd..d53e441e 100644 --- a/pyTMD/io/model.py +++ b/pyTMD/io/model.py @@ -1,11 +1,12 @@ #!/usr/bin/env python u""" model.py -Written by Tyler Sutterley (08/2023) +Written by Tyler Sutterley (09/2023) Retrieves tide model parameters for named tide models and from model definition files UPDATE HISTORY: + Updated 09/2023: fix scale values for TPXO9-atlas currents Updated 08/2023: changed ESR netCDF4 format to TMD3 format updated filenames for CATS2008-v2023 to final version Updated 06/2023: remap FES2012 e2 constituent to eps2 @@ -726,7 +727,7 @@ def current(self, m: str): self.model_file = dict(u=self.pathfinder(model_files), v=self.pathfinder(model_files)) self.projection = '4326' - self.scale = 1.0/100.0 + self.scale = 1e-4 self.version = 'v1' # model description and references self.reference = ('http://volkov.oce.orst.edu/tides/' @@ -743,7 +744,7 @@ def current(self, m: str): self.model_file = dict(u=self.pathfinder(model_files), v=self.pathfinder(model_files)) self.projection = '4326' - self.scale = 1.0/100.0 + self.scale = 1e-4 self.version = 'v2' # model description and references self.reference = 'https://www.tpxo.net/global/tpxo9-atlas' @@ -760,7 +761,7 @@ def current(self, m: str): self.model_file = dict(u=self.pathfinder(model_files), v=self.pathfinder(model_files)) self.projection = '4326' - self.scale = 1.0/100.0 + self.scale = 1e-4 self.version = 'v3' # model description and references self.reference = 'https://www.tpxo.net/global/tpxo9-atlas' @@ -777,7 +778,7 @@ def current(self, m: str): self.model_file = dict(u=self.pathfinder(model_files), v=self.pathfinder(model_files)) self.projection = '4326' - self.scale = 1.0/100.0 + self.scale = 1e-4 self.version = 'v4' # model description and references self.reference = 'https://www.tpxo.net/global/tpxo9-atlas' @@ -795,7 +796,7 @@ def current(self, m: str): self.model_file = dict(u=self.pathfinder(model_files), v=self.pathfinder(model_files)) self.projection = '4326' - self.scale = 1.0/100.0 + self.scale = 1e-4 self.version = 'v5' # model description and references self.reference = 'https://www.tpxo.net/global/tpxo9-atlas' diff --git a/pyTMD/load_constituent.py b/pyTMD/load_constituent.py index b38ded6e..69f331c2 100644 --- a/pyTMD/load_constituent.py +++ b/pyTMD/load_constituent.py @@ -1,6 +1,6 @@ #!/usr/bin/env python u""" -load_constituent.py (04/2022) +load_constituent.py (09/2023) Loads parameters for a given tidal constituent CALLING SEQUENCE: @@ -26,11 +26,13 @@ https://numpy.org/doc/stable/user/numpy-for-matlab-users.html UPDATE HISTORY: + Updated 09/2023: deprecated in favor of pyTMD.predict function Updated 04/2022: updated docstrings to numpy documentation format Updated 07/2020: add more constituents from OTPSnc and function docstrings Updated 09/2017: Rewritten in Python """ -import numpy as np +import warnings +import pyTMD.predict def load_constituent(c): """ @@ -63,51 +65,8 @@ def load_constituent(c): .. __: https://doi.org/10.1175/1520-0426(2002)019<0183:EIMOBO>2.0.CO;2 """ - # constituents array that are included in tidal program - cindex = ['m2','s2','k1','o1','n2','p1','k2','q1','2n2','mu2','nu2','l2', - 't2','j1','m1','oo1','rho1','mf','mm','ssa','m4','ms4','mn4','m6','m8', - 'mk3','s6','2sm2','2mk3'] - # species type (spherical harmonic dependence of quadrupole potential) - species_all = np.array([2,2,1,1,2,1,2,1,2,2,2,2,2,1,1,1,1,0,0,0,0,0,0, - 0,0,0,0,0,0]) - # loading love number - # alpha = correction factor for first order load tides - alpha_all = np.array([0.693,0.693,0.736,0.695,0.693,0.706,0.693,0.695,0.693, - 0.693,0.693,0.693,0.693,0.695,0.695,0.695,0.695,0.693,0.693,0.693, - 0.693,0.693,0.693,0.693,0.693,0.693,0.693,0.693,0.693]) - # omega: angular frequency of constituent, in radians - omega_all = np.array([1.405189e-04,1.454441e-04,7.292117e-05,6.759774e-05, - 1.378797e-04,7.252295e-05,1.458423e-04,6.495854e-05,1.352405e-04, - 1.355937e-04,1.382329e-04,1.431581e-04,1.452450e-04,7.556036e-05, - 7.028195e-05,7.824458e-05,6.531174e-05,0.053234e-04,0.026392e-04, - 0.003982e-04,2.810377e-04,2.859630e-04,2.783984e-04,4.215566e-04, - 5.620755e-04,2.134402e-04,4.363323e-04,1.503693e-04,2.081166e-04]) - # Astronomical arguments (relative to t0 = 1 Jan 0:00 1992) - # phases for each constituent are referred to the time when the phase of - # the forcing for that constituent is zero on the Greenwich meridian - phase_all = np.array([1.731557546,0.000000000,0.173003674,1.558553872, - 6.050721243,6.110181633,3.487600001,5.877717569,4.086699633, - 3.463115091,5.427136701,0.553986502,0.052841931,2.137025284, - 2.436575100,1.929046130,5.254133027,1.756042456,1.964021610, - 3.487600001,3.463115091,1.731557546,1.499093481,5.194672637, - 6.926230184,1.904561220,0.000000000,4.551627762,3.809122439]) - # amplitudes of equilibrium tide in m - # amplitude_all = np.array([0.242334,0.112743,0.141565,0.100661,0.046397, - amplitude_all = np.array([0.2441,0.112743,0.141565,0.100661,0.046397, - 0.046848,0.030684,0.019273,0.006141,0.007408,0.008811,0.006931,0.006608, - 0.007915,0.007915,0.004338,0.003661,0.042041,0.022191,0.019567,0.,0.,0., - 0.,0.,0.,0.,0.,0.]) - - # map between input constituent and cindex - j = [j for j,val in enumerate(cindex) if (val == c.lower())] - # set the values for the constituent - if j: - amplitude, = amplitude_all[j] - phase, = phase_all[j] - omega, = omega_all[j] - alpha, = alpha_all[j] - species, = species_all[j] - else: - amplitude = 0.0; phase = 0.0; omega = 0.0; alpha = 0.0; species = 0 - # return the values for the constituent - return (amplitude, phase, omega, alpha, species) + # raise warning for deprecated function call + warnings.warn("Deprecated. Please use pyTMD.predict instead", + DeprecationWarning) + # call updated function to not break current workflows + return pyTMD.predict._constituent_parameters(c) diff --git a/pyTMD/predict.py b/pyTMD/predict.py index 9a2bb745..678b12ed 100644 --- a/pyTMD/predict.py +++ b/pyTMD/predict.py @@ -1,7 +1,7 @@ #!/usr/bin/env python u""" predict.py -Written by Tyler Sutterley (08/2023) +Written by Tyler Sutterley (09/2023) Prediction routines for ocean, load, equilibrium and solid earth tides REFERENCES: @@ -17,10 +17,10 @@ arguments.py: loads nodal corrections for tidal constituents astro.py: computes the basic astronomical mean longitudes constants.py: calculate reference parameters for common ellipsoids - load_constituent.py: loads parameters for a given tidal constituent spatial.py: utilities for working with geospatial data UPDATE HISTORY: + Updated 09/2023: moved constituent parameters function within this module Updated 08/2023: changed ESR netCDF4 format to TMD3 format Updated 04/2023: using renamed astro mean_longitudes function using renamed arguments function for nodal corrections @@ -46,7 +46,6 @@ import pyTMD.astro from pyTMD.arguments import arguments from pyTMD.constants import constants -from pyTMD.load_constituent import load_constituent # PURPOSE: Predict tides at single times def map(t: float | np.ndarray, @@ -98,7 +97,7 @@ def map(t: float | np.ndarray, for k,c in enumerate(constituents): if corrections in ('OTIS','ATLAS','TMD3','netcdf'): # load parameters for each constituent - amp, ph, omega, alpha, species = load_constituent(c) + amp, ph, omega, alpha, species = _constituent_parameters(c) # add component for constituent to output tidal elevation th = omega*t*86400.0 + ph + pu[0,k] elif corrections in ('GOT','FES'): @@ -160,7 +159,7 @@ def drift(t: float | np.ndarray, for k,c in enumerate(constituents): if corrections in ('OTIS','ATLAS','TMD3','netcdf'): # load parameters for each constituent - amp, ph, omega, alpha, species = load_constituent(c) + amp, ph, omega, alpha, species = _constituent_parameters(c) # add component for constituent to output tidal elevation th = omega*t*86400.0 + ph + pu[:,k] elif corrections in ('GOT','FES'): @@ -222,7 +221,7 @@ def time_series(t: float | np.ndarray, for k,c in enumerate(constituents): if corrections in ('OTIS','ATLAS','TMD3','netcdf'): # load parameters for each constituent - amp, ph, omega, alpha, species = load_constituent(c) + amp, ph, omega, alpha, species = _constituent_parameters(c) # add component for constituent to output tidal time series th = omega*t*86400.0 + ph + pu[:,k] elif corrections in ('GOT','FES'): @@ -683,6 +682,86 @@ def solid_earth_tide( # return the solid earth tide return dxt +def _constituent_parameters(c): + """ + Loads parameters for a given tidal constituent + + Parameters + ---------- + c: list + tidal constituent ID + + Returns + ------- + amplitude: float + amplitude of equilibrium tide for tidal constituent (meters) + phase: float + phase of tidal constituent (radians) + omega: float + angular frequency of constituent (radians) + alpha: float + load love number of tidal constituent + species: float + spherical harmonic dependence of quadrupole potential + + References + ---------- + .. [1] G. D. Egbert and S. Y. Erofeeva, "Efficient Inverse Modeling of + Barotropic Ocean Tides," *Journal of Atmospheric and Oceanic + Technology*, 19(2), 183--204, (2002). + `doi: 10.1175/1520-0426(2002)019<0183:EIMOBO>2.0.CO;2`__ + + .. __: https://doi.org/10.1175/1520-0426(2002)019<0183:EIMOBO>2.0.CO;2 + """ + # constituents array that are included in tidal program + cindex = ['m2','s2','k1','o1','n2','p1','k2','q1','2n2','mu2','nu2','l2', + 't2','j1','m1','oo1','rho1','mf','mm','ssa','m4','ms4','mn4','m6','m8', + 'mk3','s6','2sm2','2mk3'] + # species type (spherical harmonic dependence of quadrupole potential) + species_all = np.array([2,2,1,1,2,1,2,1,2,2,2,2,2,1,1,1,1,0,0,0,0,0,0, + 0,0,0,0,0,0]) + # loading love number + # alpha = correction factor for first order load tides + alpha_all = np.array([0.693,0.693,0.736,0.695,0.693,0.706,0.693,0.695,0.693, + 0.693,0.693,0.693,0.693,0.695,0.695,0.695,0.695,0.693,0.693,0.693, + 0.693,0.693,0.693,0.693,0.693,0.693,0.693,0.693,0.693]) + # omega: angular frequency of constituent, in radians + omega_all = np.array([1.405189e-04,1.454441e-04,7.292117e-05,6.759774e-05, + 1.378797e-04,7.252295e-05,1.458423e-04,6.495854e-05,1.352405e-04, + 1.355937e-04,1.382329e-04,1.431581e-04,1.452450e-04,7.556036e-05, + 7.028195e-05,7.824458e-05,6.531174e-05,0.053234e-04,0.026392e-04, + 0.003982e-04,2.810377e-04,2.859630e-04,2.783984e-04,4.215566e-04, + 5.620755e-04,2.134402e-04,4.363323e-04,1.503693e-04,2.081166e-04]) + # Astronomical arguments (relative to t0 = 1 Jan 0:00 1992) + # phases for each constituent are referred to the time when the phase of + # the forcing for that constituent is zero on the Greenwich meridian + phase_all = np.array([1.731557546,0.000000000,0.173003674,1.558553872, + 6.050721243,6.110181633,3.487600001,5.877717569,4.086699633, + 3.463115091,5.427136701,0.553986502,0.052841931,2.137025284, + 2.436575100,1.929046130,5.254133027,1.756042456,1.964021610, + 3.487600001,3.463115091,1.731557546,1.499093481,5.194672637, + 6.926230184,1.904561220,0.000000000,4.551627762,3.809122439]) + # amplitudes of equilibrium tide in meters + # amplitude_all = np.array([0.242334,0.112743,0.141565,0.100661,0.046397, + amplitude_all = np.array([0.2441,0.112743,0.141565,0.100661,0.046397, + 0.046848,0.030684,0.019273,0.006141,0.007408,0.008811,0.006931,0.006608, + 0.007915,0.007915,0.004338,0.003661,0.042041,0.022191,0.019567,0.,0.,0., + 0.,0.,0.,0.,0.,0.]) + + # map between input constituent and cindex + j = [j for j,val in enumerate(cindex) if (val == c.lower())] + # set the values for the constituent + if j: + amplitude, = amplitude_all[j] + phase, = phase_all[j] + omega, = omega_all[j] + alpha, = alpha_all[j] + species, = species_all[j] + else: + amplitude = 0.0; phase = 0.0; omega = 0.0; alpha = 0.0; species = 0 + # return the values for the constituent + return (amplitude, phase, omega, alpha, species) + def _out_of_phase_diurnal( XYZ: np.ndarray, SXYZ: np.ndarray, diff --git a/pyTMD/spatial.py b/pyTMD/spatial.py index f50c461f..8a660090 100644 --- a/pyTMD/spatial.py +++ b/pyTMD/spatial.py @@ -23,6 +23,7 @@ UPDATE HISTORY: Updated 09/2023: add function to invert field mapping keys and values + use datetime64[ns] for parsing dates from ascii files Updated 08/2023: remove possible crs variables from output fields list place PyYAML behind try/except statement to reduce build size Updated 05/2023: use datetime parser within pyTMD.time module @@ -252,7 +253,7 @@ def from_ascii(filename: str, **kwargs): # allocate for each variable and copy variable attributes for c in columns: if (c == 'time') and kwargs['parse_dates']: - dinput[c] = np.zeros((file_lines-count), dtype='datetime64[ms]') + dinput[c] = np.zeros((file_lines-count), dtype='datetime64[ns]') else: dinput[c] = np.zeros((file_lines-count)) dinput['attributes'][c] = YAML_HEADER['header']['variables'][c] @@ -264,7 +265,7 @@ def from_ascii(filename: str, **kwargs): header = int(kwargs['header']) for c in columns: if (c == 'time') and kwargs['parse_dates']: - dinput[c] = np.zeros((file_lines-header), dtype='datetime64[ms]') + dinput[c] = np.zeros((file_lines-header), dtype='datetime64[ns]') else: dinput[c] = np.zeros((file_lines-header)) dinput['attributes'] = {c:dict() for c in columns} diff --git a/scripts/compute_tidal_currents.py b/scripts/compute_tidal_currents.py index d4131d26..2fc5cc76 100755 --- a/scripts/compute_tidal_currents.py +++ b/scripts/compute_tidal_currents.py @@ -86,7 +86,6 @@ arguments.py: load the nodal corrections for tidal constituents astro.py: computes the basic astronomical mean longitudes convert_crs.py: convert points to and from Coordinates Reference Systems - load_constituent.py: loads parameters for a given tidal constituent 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 netcdf models diff --git a/scripts/compute_tidal_elevations.py b/scripts/compute_tidal_elevations.py index 9131e7f4..f9077b9d 100755 --- a/scripts/compute_tidal_elevations.py +++ b/scripts/compute_tidal_elevations.py @@ -89,7 +89,6 @@ arguments.py: load the nodal corrections for tidal constituents astro.py: computes the basic astronomical mean longitudes convert_crs.py: convert points to and from Coordinates Reference Systems - load_constituent.py: loads parameters for a given tidal constituent 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 netcdf models diff --git a/test/test_download_and_read.py b/test/test_download_and_read.py index 3d155465..0855e332 100644 --- a/test/test_download_and_read.py +++ b/test/test_download_and_read.py @@ -54,8 +54,8 @@ import pyTMD.predict import pyTMD.time import pyTMD.utilities -import pyTMD.check_tide_points -import pyTMD.tidal_ellipse +import pyTMD.check_points +import pyTMD.ellipse from oct2py import octave # current file path @@ -227,7 +227,7 @@ def test_read_CATS2008(self, ny=2026, nx=1663): def test_check_CATS2008(self): lons = np.zeros((10)) + 178.0 lats = -45.0 - np.arange(10)*5.0 - obs = pyTMD.check_tide_points(lons, lats, DIRECTORY=filepath, + obs = pyTMD.check_points(lons, lats, DIRECTORY=filepath, MODEL='CATS2008', EPSG=4326) exp = np.array([False, False, False, False, True, True, True, True, False, False]) @@ -531,7 +531,7 @@ def test_tidal_ellipse(self): # compute tidal ellipse parameters for python program test = {} test['umajor'],test['uminor'],test['uincl'],test['uphase'] = \ - pyTMD.tidal_ellipse(hc1['U'],hc1['V']) + pyTMD.ellipse(hc1['U'],hc1['V']) # compute tidal ellipse parameters for TMD matlab program valid = {} valid['umajor'],valid['uminor'],valid['uincl'],valid['uphase'] = \ diff --git a/test/test_fes_predict.py b/test/test_fes_predict.py index 7b10bee9..3a4674a1 100644 --- a/test/test_fes_predict.py +++ b/test/test_fes_predict.py @@ -38,7 +38,7 @@ import pyTMD.io.model import pyTMD.utilities import pyTMD.predict -import pyTMD.check_tide_points +import pyTMD.check_points # current file path filename = inspect.getframeinfo(inspect.currentframe()).filename @@ -80,7 +80,7 @@ def download_model(aws_access_key_id,aws_secret_access_key,aws_region_name): def test_check_FES2014(): lons = np.zeros((10)) + 178.0 lats = -45.0 - np.arange(10)*5.0 - obs = pyTMD.check_tide_points(lons, lats, DIRECTORY=filepath, + obs = pyTMD.check_points(lons, lats, DIRECTORY=filepath, MODEL='FES2014', GZIP=True, EPSG=4326) exp = np.array([True, True, True, True, True, True, True, True, False, False]) diff --git a/test/test_perth3_read.py b/test/test_perth3_read.py index ac7fd2da..9ee0aca2 100644 --- a/test/test_perth3_read.py +++ b/test/test_perth3_read.py @@ -40,7 +40,7 @@ import pyTMD.utilities import pyTMD.predict import pyTMD.compute_tide_corrections -import pyTMD.check_tide_points +import pyTMD.check_points # current file path filename = inspect.getframeinfo(inspect.currentframe()).filename @@ -216,7 +216,7 @@ def test_compare_GOT47(METHOD): def test_check_GOT47(): lons = np.zeros((10)) + 178.0 lats = -45.0 - np.arange(10)*5.0 - obs = pyTMD.check_tide_points(lons, lats, DIRECTORY=filepath, + obs = pyTMD.check_points(lons, lats, DIRECTORY=filepath, MODEL='GOT4.7', GZIP=True, EPSG=4326) exp = np.array([True, True, True, True, True, True, True, True, False, False])