pyTMD 2.2.1__tar.gz → 2.2.2__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.
- {pytmd-2.2.1 → pytmd-2.2.2}/CITATION.cff +3 -3
- {pytmd-2.2.1 → pytmd-2.2.2}/PKG-INFO +13 -17
- {pytmd-2.2.1 → pytmd-2.2.2}/README.rst +10 -10
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/__init__.py +1 -8
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/arguments.py +13 -7
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/astro.py +2 -2
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/compute.py +5 -5
- pytmd-2.2.2/pyTMD/crs.py +247 -0
- pytmd-2.2.2/pyTMD/data/d1921_tab.txt +21 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/constituents.py +16 -12
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/predict.py +16 -3
- pytmd-2.2.2/pyTMD/spatial.py +1419 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD.egg-info/PKG-INFO +13 -17
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD.egg-info/SOURCES.txt +1 -9
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD.egg-info/requires.txt +0 -4
- {pytmd-2.2.1 → pytmd-2.2.2}/pyproject.toml +3 -9
- pytmd-2.2.2/version.txt +1 -0
- pytmd-2.2.1/pyTMD/check_points.py +0 -119
- pytmd-2.2.1/pyTMD/crs.py +0 -629
- pytmd-2.2.1/pyTMD/eop.py +0 -240
- pytmd-2.2.1/pyTMD/spatial.py +0 -2275
- pytmd-2.2.1/pyTMD/time.py +0 -355
- pytmd-2.2.1/scripts/compute_LPET_elevations.py +0 -413
- pytmd-2.2.1/scripts/compute_LPT_displacements.py +0 -533
- pytmd-2.2.1/scripts/compute_OPT_displacements.py +0 -565
- pytmd-2.2.1/scripts/compute_SET_displacements.py +0 -511
- pytmd-2.2.1/scripts/compute_tidal_currents.py +0 -640
- pytmd-2.2.1/scripts/compute_tidal_elevations.py +0 -646
- pytmd-2.2.1/version.txt +0 -1
- {pytmd-2.2.1 → pytmd-2.2.2}/.gitignore +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/CODE_OF_CONDUCT.rst +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/CONTRIBUTORS.rst +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/LICENSE +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/MANIFEST.in +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/AVISO.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/ESR.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/GSFC.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/README.rst +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/TPXO.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/_model_to_database.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/_providers_to_database.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/_update_providers.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/providers/providers.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/compute_tide_corrections.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/ce1973_tab1.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/ct1971_tab5.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/database.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/doodson.json +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/opoleloadcoefcmcor.txt.gz +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/tab5.2e.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/tab5.3a.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/data/tab5.3b.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/ellipse.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/interpolate.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/ATLAS.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/FES.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/GOT.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/IERS.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/OTIS.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/__init__.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/io/model.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/math.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/solve/__init__.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/solve/constants.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/tools.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/utilities.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD/version.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD.egg-info/dependency_links.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/pyTMD.egg-info/top_level.txt +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/arcticdata_tides.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/aviso_fes_tides.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/gsfc_got_tides.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/reduce_OTIS_files.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/usap_cats_tides.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/scripts/verify_box_tpxo.py +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/setup.cfg +0 -0
- {pytmd-2.2.1 → pytmd-2.2.2}/setup.py +0 -0
|
@@ -31,13 +31,13 @@ identifiers:
|
|
|
31
31
|
- type: doi
|
|
32
32
|
value: 10.5281/zenodo.5555395
|
|
33
33
|
description: Zenodo Archive
|
|
34
|
-
repository-code: 'https://github.com/
|
|
34
|
+
repository-code: 'https://github.com/pyTMD/pyTMD'
|
|
35
35
|
url: 'https://pytmd.readthedocs.io'
|
|
36
36
|
repository: 'https://pypi.org/project/pyTMD'
|
|
37
37
|
repository-artifact: 'https://anaconda.org/conda-forge/pytmd'
|
|
38
38
|
doi: "10.5281/zenodo.5555395"
|
|
39
|
-
version: "2.2.
|
|
40
|
-
date-released: "2025-02-
|
|
39
|
+
version: "2.2.2"
|
|
40
|
+
date-released: "2025-02-19"
|
|
41
41
|
keywords:
|
|
42
42
|
- Ocean Tides
|
|
43
43
|
- Load Tides
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: pyTMD
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Python-based tidal prediction software for estimating ocean, load, solid Earth and pole tides
|
|
5
5
|
Author: Tyler Sutterley
|
|
6
6
|
Author-email: tsutterl@uw.edu
|
|
@@ -29,8 +29,8 @@ License: MIT License
|
|
|
29
29
|
|
|
30
30
|
Project-URL: Homepage, https://pytmd.readthedocs.io
|
|
31
31
|
Project-URL: Documentation, https://pytmd.readthedocs.io
|
|
32
|
-
Project-URL: Repository, https://github.com/
|
|
33
|
-
Project-URL: Issues, https://github.com/
|
|
32
|
+
Project-URL: Repository, https://github.com/pyTMD/pyTMD
|
|
33
|
+
Project-URL: Issues, https://github.com/pyTMD/pyTMD/issues
|
|
34
34
|
Keywords: Ocean Tides,Load Tides,Pole Tides,Solid Earth Tides,Tidal Prediction
|
|
35
35
|
Classifier: Development Status :: 3 - Alpha
|
|
36
36
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -70,16 +70,12 @@ Requires-Dist: sphinx-design; extra == "doc"
|
|
|
70
70
|
Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
|
71
71
|
Provides-Extra: all
|
|
72
72
|
Requires-Dist: cartopy; extra == "all"
|
|
73
|
-
Requires-Dist: gdal; extra == "all"
|
|
74
|
-
Requires-Dist: h5py; extra == "all"
|
|
75
73
|
Requires-Dist: ipyleaflet; extra == "all"
|
|
76
74
|
Requires-Dist: ipywidgets; extra == "all"
|
|
77
75
|
Requires-Dist: jplephem; extra == "all"
|
|
78
76
|
Requires-Dist: matplotlib; extra == "all"
|
|
79
|
-
Requires-Dist: mpi4py; extra == "all"
|
|
80
77
|
Requires-Dist: notebook; extra == "all"
|
|
81
78
|
Requires-Dist: pandas; extra == "all"
|
|
82
|
-
Requires-Dist: pyyaml; extra == "all"
|
|
83
79
|
Provides-Extra: dev
|
|
84
80
|
Requires-Dist: flake8; extra == "dev"
|
|
85
81
|
Requires-Dist: pytest>=4.6; extra == "dev"
|
|
@@ -93,26 +89,26 @@ pyTMD
|
|
|
93
89
|
|
|
94
90
|
|License|
|
|
95
91
|
|Documentation Status|
|
|
96
|
-
|Coverage Status|
|
|
97
92
|
|PyPI|
|
|
98
93
|
|conda-forge|
|
|
94
|
+
|commits-since|
|
|
99
95
|
|zenodo|
|
|
100
96
|
|
|
101
|
-
.. |License| image:: https://img.shields.io/github/license/
|
|
102
|
-
:target: https://github.com/
|
|
97
|
+
.. |License| image:: https://img.shields.io/github/license/pyTMD/pyTMD
|
|
98
|
+
:target: https://github.com/pyTMD/pyTMD/blob/main/LICENSE
|
|
103
99
|
|
|
104
100
|
.. |Documentation Status| image:: https://readthedocs.org/projects/pytmd/badge/?version=latest
|
|
105
101
|
:target: https://pytmd.readthedocs.io/en/latest/?badge=latest
|
|
106
102
|
|
|
107
|
-
.. |Coverage Status| image:: https://codecov.io/gh/tsutterley/pyTMD/branch/main/graph/badge.svg
|
|
108
|
-
:target: https://codecov.io/gh/tsutterley/pyTMD
|
|
109
|
-
|
|
110
103
|
.. |PyPI| image:: https://img.shields.io/pypi/v/pyTMD.svg
|
|
111
104
|
:target: https://pypi.python.org/pypi/pyTMD/
|
|
112
105
|
|
|
113
106
|
.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytmd
|
|
114
107
|
:target: https://anaconda.org/conda-forge/pytmd
|
|
115
108
|
|
|
109
|
+
.. |commits-since| image:: https://img.shields.io/github/commits-since/pyTMD/pyTMD/latest
|
|
110
|
+
:target: https://github.com/pyTMD/pyTMD/releases
|
|
111
|
+
|
|
116
112
|
.. |zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.5555395.svg
|
|
117
113
|
:target: https://doi.org/10.5281/zenodo.5555395
|
|
118
114
|
|
|
@@ -149,7 +145,7 @@ Development version from GitHub:
|
|
|
149
145
|
|
|
150
146
|
.. code-block:: bash
|
|
151
147
|
|
|
152
|
-
python3 -m pip install git+https://github.com/
|
|
148
|
+
python3 -m pip install git+https://github.com/pyTMD/pyTMD.git
|
|
153
149
|
|
|
154
150
|
Dependencies
|
|
155
151
|
############
|
|
@@ -178,9 +174,9 @@ Download
|
|
|
178
174
|
########
|
|
179
175
|
|
|
180
176
|
| The program homepage is:
|
|
181
|
-
| https://github.com/
|
|
177
|
+
| https://github.com/pyTMD/pyTMD
|
|
182
178
|
| A zip archive of the latest version is available directly at:
|
|
183
|
-
| https://github.com/
|
|
179
|
+
| https://github.com/pyTMD/pyTMD/archive/main.zip
|
|
184
180
|
|
|
185
181
|
Alternative Software
|
|
186
182
|
####################
|
|
@@ -204,7 +200,7 @@ Contributing
|
|
|
204
200
|
############
|
|
205
201
|
|
|
206
202
|
This project contains work and contributions from the `scientific community <./CONTRIBUTORS.rst>`_.
|
|
207
|
-
If you would like to contribute to the project, please have a look at the `open issues <https://github.com/
|
|
203
|
+
If you would like to contribute to the project, please have a look at the `open issues <https://github.com/pyTMD/pyTMD/issues>`_ and `discussions board <https://github.com/pyTMD/pyTMD/discussions>`_.
|
|
208
204
|
|
|
209
205
|
Credits
|
|
210
206
|
#######
|
|
@@ -4,26 +4,26 @@ pyTMD
|
|
|
4
4
|
|
|
5
5
|
|License|
|
|
6
6
|
|Documentation Status|
|
|
7
|
-
|Coverage Status|
|
|
8
7
|
|PyPI|
|
|
9
8
|
|conda-forge|
|
|
9
|
+
|commits-since|
|
|
10
10
|
|zenodo|
|
|
11
11
|
|
|
12
|
-
.. |License| image:: https://img.shields.io/github/license/
|
|
13
|
-
:target: https://github.com/
|
|
12
|
+
.. |License| image:: https://img.shields.io/github/license/pyTMD/pyTMD
|
|
13
|
+
:target: https://github.com/pyTMD/pyTMD/blob/main/LICENSE
|
|
14
14
|
|
|
15
15
|
.. |Documentation Status| image:: https://readthedocs.org/projects/pytmd/badge/?version=latest
|
|
16
16
|
:target: https://pytmd.readthedocs.io/en/latest/?badge=latest
|
|
17
17
|
|
|
18
|
-
.. |Coverage Status| image:: https://codecov.io/gh/tsutterley/pyTMD/branch/main/graph/badge.svg
|
|
19
|
-
:target: https://codecov.io/gh/tsutterley/pyTMD
|
|
20
|
-
|
|
21
18
|
.. |PyPI| image:: https://img.shields.io/pypi/v/pyTMD.svg
|
|
22
19
|
:target: https://pypi.python.org/pypi/pyTMD/
|
|
23
20
|
|
|
24
21
|
.. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pytmd
|
|
25
22
|
:target: https://anaconda.org/conda-forge/pytmd
|
|
26
23
|
|
|
24
|
+
.. |commits-since| image:: https://img.shields.io/github/commits-since/pyTMD/pyTMD/latest
|
|
25
|
+
:target: https://github.com/pyTMD/pyTMD/releases
|
|
26
|
+
|
|
27
27
|
.. |zenodo| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.5555395.svg
|
|
28
28
|
:target: https://doi.org/10.5281/zenodo.5555395
|
|
29
29
|
|
|
@@ -60,7 +60,7 @@ Development version from GitHub:
|
|
|
60
60
|
|
|
61
61
|
.. code-block:: bash
|
|
62
62
|
|
|
63
|
-
python3 -m pip install git+https://github.com/
|
|
63
|
+
python3 -m pip install git+https://github.com/pyTMD/pyTMD.git
|
|
64
64
|
|
|
65
65
|
Dependencies
|
|
66
66
|
############
|
|
@@ -89,9 +89,9 @@ Download
|
|
|
89
89
|
########
|
|
90
90
|
|
|
91
91
|
| The program homepage is:
|
|
92
|
-
| https://github.com/
|
|
92
|
+
| https://github.com/pyTMD/pyTMD
|
|
93
93
|
| A zip archive of the latest version is available directly at:
|
|
94
|
-
| https://github.com/
|
|
94
|
+
| https://github.com/pyTMD/pyTMD/archive/main.zip
|
|
95
95
|
|
|
96
96
|
Alternative Software
|
|
97
97
|
####################
|
|
@@ -115,7 +115,7 @@ Contributing
|
|
|
115
115
|
############
|
|
116
116
|
|
|
117
117
|
This project contains work and contributions from the `scientific community <./CONTRIBUTORS.rst>`_.
|
|
118
|
-
If you would like to contribute to the project, please have a look at the `open issues <https://github.com/
|
|
118
|
+
If you would like to contribute to the project, please have a look at the `open issues <https://github.com/pyTMD/pyTMD/issues>`_ and `discussions board <https://github.com/pyTMD/pyTMD/discussions>`_.
|
|
119
119
|
|
|
120
120
|
Credits
|
|
121
121
|
#######
|
|
@@ -24,14 +24,9 @@ import pyTMD.utilities
|
|
|
24
24
|
import pyTMD.version
|
|
25
25
|
from pyTMD import io
|
|
26
26
|
from pyTMD import solve
|
|
27
|
-
from pyTMD.crs import
|
|
28
|
-
crs,
|
|
29
|
-
datum,
|
|
30
|
-
_ellipsoids
|
|
31
|
-
)
|
|
27
|
+
from pyTMD.crs import crs
|
|
32
28
|
|
|
33
29
|
# Deprecated functions
|
|
34
|
-
from pyTMD.check_points import check_points
|
|
35
30
|
from pyTMD.compute_tide_corrections import (
|
|
36
31
|
compute_corrections,
|
|
37
32
|
compute_tide_corrections,
|
|
@@ -40,8 +35,6 @@ from pyTMD.compute_tide_corrections import (
|
|
|
40
35
|
compute_OPT_corrections,
|
|
41
36
|
compute_SET_corrections,
|
|
42
37
|
)
|
|
43
|
-
import pyTMD.eop
|
|
44
|
-
import pyTMD.time
|
|
45
38
|
|
|
46
39
|
# get semantic version from setuptools-scm
|
|
47
40
|
__version__ = pyTMD.version.version
|
|
@@ -40,6 +40,8 @@ REFERENCES:
|
|
|
40
40
|
|
|
41
41
|
UPDATE HISTORY:
|
|
42
42
|
Updated 02/2025: add option to make doodson numbers strings
|
|
43
|
+
add Doodson number convention for converting 11 to E
|
|
44
|
+
add Doodson (1921) table for coefficients missing from Cartwright tables
|
|
43
45
|
Updated 12/2024: added function to calculate tidal aliasing periods
|
|
44
46
|
Updated 11/2024: allow variable case for Doodson number formalisms
|
|
45
47
|
fix species in constituent parameters for complex tides
|
|
@@ -1489,6 +1491,8 @@ def _love_numbers(
|
|
|
1489
1491
|
# return the Love numbers for frequency
|
|
1490
1492
|
return (h2, k2, l2)
|
|
1491
1493
|
|
|
1494
|
+
# Doodson (1921) table with values missing from Cartwright tables
|
|
1495
|
+
_d1921_table = get_data_path(['data','d1921_tab.txt'])
|
|
1492
1496
|
# Cartwright and Tayler (1971) table with 3rd-degree values
|
|
1493
1497
|
_ct1971_table_5 = get_data_path(['data','ct1971_tab5.txt'])
|
|
1494
1498
|
# Cartwright and Edden (1973) table with updated values
|
|
@@ -1561,13 +1565,14 @@ def _to_doodson_number(coef: list | np.ndarray, **kwargs):
|
|
|
1561
1565
|
# add 5 to values following Doodson convention (prevent negatives)
|
|
1562
1566
|
coef[1:] += 5
|
|
1563
1567
|
# check for unsupported constituents
|
|
1564
|
-
if (np.any(coef < 0) or np.any(coef >
|
|
1568
|
+
if (np.any(coef < 0) or np.any(coef > 11)) and kwargs['raise_error']:
|
|
1565
1569
|
raise ValueError('Unsupported constituent')
|
|
1566
|
-
elif (np.any(coef < 0) or np.any(coef >
|
|
1570
|
+
elif (np.any(coef < 0) or np.any(coef > 11)):
|
|
1567
1571
|
return None
|
|
1568
|
-
elif np.any(coef == 10):
|
|
1569
|
-
# convert to
|
|
1570
|
-
|
|
1572
|
+
elif np.any(coef == 10) or np.any(coef == 11):
|
|
1573
|
+
# convert coefficients to strings
|
|
1574
|
+
# replace 10 with X and 11 with E (Doodson convention)
|
|
1575
|
+
DO = [str(v).replace('10','X').replace('11','E') for v in coef]
|
|
1571
1576
|
# convert to Doodson number
|
|
1572
1577
|
return np.str_('{0}{1}{2}.{3}{4}{5}'.format(*DO))
|
|
1573
1578
|
else:
|
|
@@ -1614,8 +1619,9 @@ def _from_doodson_number(DO: str | float | np.ndarray, **kwargs):
|
|
|
1614
1619
|
Doodson coefficients (Cartwright numbers) for constituent
|
|
1615
1620
|
"""
|
|
1616
1621
|
# convert from Doodson number to Cartwright numbers
|
|
1617
|
-
|
|
1618
|
-
coef = np.array(
|
|
1622
|
+
# replace 10 with X and 11 with E (Doodson convention)
|
|
1623
|
+
coef = np.array([c.replace('X', '10').replace('E', '11')
|
|
1624
|
+
for c in re.findall(r'\w', str(DO).zfill(7))], dtype=int)
|
|
1619
1625
|
# remove 5 from values following Doodson convention
|
|
1620
1626
|
coef[1:] -= 5
|
|
1621
1627
|
return coef
|
|
@@ -8,8 +8,8 @@ PYTHON DEPENDENCIES:
|
|
|
8
8
|
numpy: Scientific Computing Tools For Python
|
|
9
9
|
https://numpy.org
|
|
10
10
|
https://numpy.org/doc/stable/user/numpy-for-matlab-users.html
|
|
11
|
-
|
|
12
|
-
https://
|
|
11
|
+
jplephem: Astronomical Ephemeris for Python
|
|
12
|
+
https://pypi.org/project/jplephem/
|
|
13
13
|
|
|
14
14
|
REFERENCES:
|
|
15
15
|
Jean Meeus, Astronomical Algorithms, 2nd edition, 1998.
|
|
@@ -960,7 +960,7 @@ def LPT_displacements(
|
|
|
960
960
|
|
|
961
961
|
# validate input arguments
|
|
962
962
|
assert TIME.lower() in ('gps', 'loran', 'tai', 'utc', 'datetime')
|
|
963
|
-
assert ELLIPSOID.upper() in pyTMD._ellipsoids
|
|
963
|
+
assert ELLIPSOID.upper() in pyTMD.spatial._ellipsoids
|
|
964
964
|
assert CONVENTION.isdigit() and CONVENTION in timescale.eop._conventions
|
|
965
965
|
# determine input data type based on variable dimensions
|
|
966
966
|
if not TYPE:
|
|
@@ -999,7 +999,7 @@ def LPT_displacements(
|
|
|
999
999
|
# degrees to radians
|
|
1000
1000
|
dtr = np.pi/180.0
|
|
1001
1001
|
# earth and physical parameters for ellipsoid
|
|
1002
|
-
units = pyTMD.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1002
|
+
units = pyTMD.spatial.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1003
1003
|
# tidal love/shida numbers appropriate for the load tide
|
|
1004
1004
|
hb2 = 0.6207
|
|
1005
1005
|
lb2 = 0.0836
|
|
@@ -1167,7 +1167,7 @@ def OPT_displacements(
|
|
|
1167
1167
|
|
|
1168
1168
|
# validate input arguments
|
|
1169
1169
|
assert TIME.lower() in ('gps', 'loran', 'tai', 'utc', 'datetime')
|
|
1170
|
-
assert ELLIPSOID.upper() in pyTMD._ellipsoids
|
|
1170
|
+
assert ELLIPSOID.upper() in pyTMD.spatial._ellipsoids
|
|
1171
1171
|
assert CONVENTION.isdigit() and CONVENTION in timescale.eop._conventions
|
|
1172
1172
|
assert METHOD.lower() in ('bilinear', 'spline', 'linear', 'nearest')
|
|
1173
1173
|
# determine input data type based on variable dimensions
|
|
@@ -1214,7 +1214,7 @@ def OPT_displacements(
|
|
|
1214
1214
|
# degrees to radians
|
|
1215
1215
|
dtr = np.pi/180.0
|
|
1216
1216
|
# earth and physical parameters for ellipsoid
|
|
1217
|
-
units = pyTMD.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1217
|
+
units = pyTMD.spatial.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1218
1218
|
# mean equatorial gravitational acceleration [m/s^2]
|
|
1219
1219
|
ge = 9.7803278
|
|
1220
1220
|
# density of sea water [kg/m^3]
|
|
@@ -1427,7 +1427,7 @@ def SET_displacements(
|
|
|
1427
1427
|
nt = len(ts)
|
|
1428
1428
|
|
|
1429
1429
|
# earth and physical parameters for ellipsoid
|
|
1430
|
-
units = pyTMD.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1430
|
+
units = pyTMD.spatial.datum(ellipsoid=ELLIPSOID, units='MKS')
|
|
1431
1431
|
|
|
1432
1432
|
# convert input coordinates to cartesian
|
|
1433
1433
|
X, Y, Z = pyTMD.spatial.to_cartesian(lon, lat,
|
pytmd-2.2.2/pyTMD/crs.py
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
u"""
|
|
3
|
+
crs.py
|
|
4
|
+
Written by Tyler Sutterley (09/2024)
|
|
5
|
+
Coordinates Reference System (CRS) class
|
|
6
|
+
|
|
7
|
+
CALLING SEQUENCE:
|
|
8
|
+
x, y = pyTMD.crs().convert(lon, lat, PROJ, 'F')
|
|
9
|
+
lon, lat = pyTMD.crs().convert(x, y, PROJ, 'B')
|
|
10
|
+
|
|
11
|
+
INPUTS:
|
|
12
|
+
i1: longitude ('F') or projection easting x ('B')
|
|
13
|
+
i2: latitude ('F') or projection northing y ('B')
|
|
14
|
+
PROJ: spatial reference system for coordinate transformations
|
|
15
|
+
BF: backwards ('B') or forward ('F') translations
|
|
16
|
+
|
|
17
|
+
OPTIONS:
|
|
18
|
+
EPSG: spatial reference system code for input (F) and output (B) coordinates
|
|
19
|
+
|
|
20
|
+
OUTPUTS:
|
|
21
|
+
o1: projection easting x ('F') or longitude ('B')
|
|
22
|
+
o2: projection northing y ('F') or latitude ('B')
|
|
23
|
+
|
|
24
|
+
PYTHON DEPENDENCIES:
|
|
25
|
+
numpy: Scientific Computing Tools For Python
|
|
26
|
+
https://numpy.org
|
|
27
|
+
https://numpy.org/doc/stable/user/numpy-for-matlab-users.html
|
|
28
|
+
pyproj: Python interface to PROJ library
|
|
29
|
+
https://pypi.org/project/pyproj/
|
|
30
|
+
https://pyproj4.github.io/pyproj/
|
|
31
|
+
|
|
32
|
+
UPDATE HISTORY:
|
|
33
|
+
Updated 09/2024: added function for idealized Arctic Azimuthal projection
|
|
34
|
+
complete refactor to use JSON dictionary format for model projections
|
|
35
|
+
Updated 07/2024: added function to get the CRS transform
|
|
36
|
+
Updated 05/2024: make subscriptable and allow item assignment
|
|
37
|
+
Updated 04/2024: use wrapper to importlib for optional dependencies
|
|
38
|
+
Updated 02/2024: changed class name for ellipsoid parameters to datum
|
|
39
|
+
Updated 12/2023: converted conversion functions to class
|
|
40
|
+
Updated 03/2023: add basic variable typing to function inputs
|
|
41
|
+
renamed coordinate reference system conversion functions
|
|
42
|
+
Updated 02/2023: use named exception before passing to custom
|
|
43
|
+
Updated 11/2022: place some imports within try/except statements
|
|
44
|
+
use f-strings for formatting verbose or ascii output
|
|
45
|
+
Updated 04/2022: updated docstrings to numpy documentation format
|
|
46
|
+
Updated 09/2021: added function for using custom projections
|
|
47
|
+
Updated 06/2021: added 3413 for new 1km Greenland model from ESR
|
|
48
|
+
Updated 08/2020: using conversion protocols following pyproj-2 updates
|
|
49
|
+
https://pyproj4.github.io/pyproj/stable/gotchas.html
|
|
50
|
+
Updated 07/2020: added function docstrings. changed function name
|
|
51
|
+
Updated 03/2020: remove commented coordinate conversion functions
|
|
52
|
+
Updated 11/2019: using pyproj for coordinate conversions
|
|
53
|
+
Written 09/2017
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
from __future__ import annotations
|
|
57
|
+
|
|
58
|
+
import logging
|
|
59
|
+
import numpy as np
|
|
60
|
+
from pyTMD.utilities import import_dependency
|
|
61
|
+
# attempt imports
|
|
62
|
+
pyproj = import_dependency('pyproj')
|
|
63
|
+
|
|
64
|
+
__all__ = [
|
|
65
|
+
'crs',
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
class crs:
|
|
69
|
+
"""Coordinate Reference System transformations for tide models
|
|
70
|
+
|
|
71
|
+
Attributes
|
|
72
|
+
----------
|
|
73
|
+
name: str
|
|
74
|
+
Projection name
|
|
75
|
+
transformer: obj
|
|
76
|
+
``pyproj`` transformer for changing coordinate reference system
|
|
77
|
+
"""
|
|
78
|
+
def __init__(self):
|
|
79
|
+
self.name = None
|
|
80
|
+
self.transformer = None
|
|
81
|
+
self._direction = None
|
|
82
|
+
|
|
83
|
+
def convert(self,
|
|
84
|
+
i1: np.ndarray,
|
|
85
|
+
i2: np.ndarray,
|
|
86
|
+
PROJ: str | dict,
|
|
87
|
+
BF: str,
|
|
88
|
+
EPSG: int | str = 4326
|
|
89
|
+
):
|
|
90
|
+
"""
|
|
91
|
+
Converts points to and from Coordinates Reference Systems (CRS)
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
i1: np.ndarray
|
|
96
|
+
Input x-coordinates
|
|
97
|
+
i2: np.ndarray
|
|
98
|
+
Input y-coordinates
|
|
99
|
+
PROJ: str or dict
|
|
100
|
+
Spatial reference system for coordinate transformations
|
|
101
|
+
BF: str
|
|
102
|
+
Direction of transformation
|
|
103
|
+
|
|
104
|
+
- ``'B'``: backwards
|
|
105
|
+
- ``'F'``: forwards
|
|
106
|
+
EPSG: int or str, default 4326 (WGS84 Latitude/Longitude)
|
|
107
|
+
input (``'F'``) or output (``'B'``) coordinate system
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
o1: np.ndarray
|
|
112
|
+
Output transformed x-coordinates
|
|
113
|
+
o2: np.ndarray
|
|
114
|
+
Output transformed y-coordinates
|
|
115
|
+
"""
|
|
116
|
+
# name of the projection
|
|
117
|
+
self.name = PROJ
|
|
118
|
+
# get the CRS and transform direction
|
|
119
|
+
self.get(PROJ)
|
|
120
|
+
self._direction = BF[0].upper()
|
|
121
|
+
# run conversion program and return values
|
|
122
|
+
return self.transform(i1, i2, EPSG=EPSG)
|
|
123
|
+
|
|
124
|
+
# PURPOSE: try to get the projection information
|
|
125
|
+
def get(self, PROJ: str | dict):
|
|
126
|
+
"""
|
|
127
|
+
Tries to get the coordinate reference system
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
PROJ: str or dict
|
|
132
|
+
Spatial reference system for coordinate transformations
|
|
133
|
+
"""
|
|
134
|
+
# get the coordinate reference system
|
|
135
|
+
try:
|
|
136
|
+
self.crs = self.from_input(PROJ)
|
|
137
|
+
self.name = self.crs.name
|
|
138
|
+
except Exception as exc:
|
|
139
|
+
pass
|
|
140
|
+
else:
|
|
141
|
+
return self
|
|
142
|
+
# projection not found or available
|
|
143
|
+
raise pyproj.exceptions.CRSError
|
|
144
|
+
|
|
145
|
+
def transform(self,
|
|
146
|
+
i1: np.ndarray,
|
|
147
|
+
i2: np.ndarray,
|
|
148
|
+
EPSG: int | str = 4326,
|
|
149
|
+
**kwargs):
|
|
150
|
+
"""
|
|
151
|
+
Performs Coordinates Reference System (CRS) transformations
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
i1: np.ndarray
|
|
156
|
+
Input x-coordinates
|
|
157
|
+
i2: np.ndarray
|
|
158
|
+
Input y-coordinates
|
|
159
|
+
EPSG: int or str, default 4326 (WGS84 Latitude/Longitude)
|
|
160
|
+
input (``'F'``) or output (``'B'``) coordinate system
|
|
161
|
+
kwargs: dict
|
|
162
|
+
Keyword arguments for the transformation
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
o1: np.ndarray
|
|
167
|
+
Output transformed x-coordinates
|
|
168
|
+
o2: np.ndarray
|
|
169
|
+
Output transformed y-coordinates
|
|
170
|
+
"""
|
|
171
|
+
# set the direction of the transformation
|
|
172
|
+
kwargs.setdefault('direction', self.direction)
|
|
173
|
+
# get the coordinate reference system and transform
|
|
174
|
+
source_crs = self.from_input(EPSG)
|
|
175
|
+
self.transformer = pyproj.Transformer.from_crs(
|
|
176
|
+
source_crs, self.crs, always_xy=True)
|
|
177
|
+
# convert coordinate reference system
|
|
178
|
+
o1, o2 = self.transformer.transform(i1, i2, **kwargs)
|
|
179
|
+
# return the transformed coordinates
|
|
180
|
+
return (o1, o2)
|
|
181
|
+
|
|
182
|
+
# PURPOSE: try to get the projection information
|
|
183
|
+
def from_input(self, PROJECTION: int | str | dict):
|
|
184
|
+
"""
|
|
185
|
+
Attempt to retrieve the Coordinate Reference System
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
PROJECTION: int, str or dict
|
|
190
|
+
Coordinate Reference System
|
|
191
|
+
"""
|
|
192
|
+
# coordinate reference system dictoinary
|
|
193
|
+
try:
|
|
194
|
+
CRS = pyproj.CRS.from_user_input(PROJECTION)
|
|
195
|
+
except (ValueError, pyproj.exceptions.CRSError):
|
|
196
|
+
pass
|
|
197
|
+
else:
|
|
198
|
+
return CRS
|
|
199
|
+
# EPSG projection code
|
|
200
|
+
try:
|
|
201
|
+
CRS = pyproj.CRS.from_epsg(int(PROJECTION))
|
|
202
|
+
except (ValueError, pyproj.exceptions.CRSError):
|
|
203
|
+
pass
|
|
204
|
+
else:
|
|
205
|
+
return CRS
|
|
206
|
+
# coordinate reference system string
|
|
207
|
+
try:
|
|
208
|
+
CRS = pyproj.CRS.from_string(PROJECTION)
|
|
209
|
+
except (ValueError, pyproj.exceptions.CRSError):
|
|
210
|
+
pass
|
|
211
|
+
else:
|
|
212
|
+
return CRS
|
|
213
|
+
# no projection can be made
|
|
214
|
+
raise pyproj.exceptions.CRSError
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def direction(self):
|
|
218
|
+
"""
|
|
219
|
+
``pyproj`` direction of the coordinate transform
|
|
220
|
+
"""
|
|
221
|
+
# convert from input coordinates to model coordinates
|
|
222
|
+
if (self._direction is None) or (self._direction.upper() == 'F'):
|
|
223
|
+
return pyproj.enums.TransformDirection.FORWARD
|
|
224
|
+
# convert from model coordinates to coordinates
|
|
225
|
+
elif (self._direction.upper() == 'B'):
|
|
226
|
+
return pyproj.enums.TransformDirection.INVERSE
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def is_geographic(self):
|
|
230
|
+
"""
|
|
231
|
+
Check if the coordinate reference system is geographic
|
|
232
|
+
"""
|
|
233
|
+
return self.crs.is_geographic
|
|
234
|
+
|
|
235
|
+
def __str__(self):
|
|
236
|
+
"""String representation of the ``crs`` object
|
|
237
|
+
"""
|
|
238
|
+
properties = ['pyTMD.crs']
|
|
239
|
+
properties.append(f" name: {self.name}")
|
|
240
|
+
properties.append(f" direction: {self.direction.name}")
|
|
241
|
+
return '\n'.join(properties)
|
|
242
|
+
|
|
243
|
+
def __getitem__(self, key):
|
|
244
|
+
return getattr(self, key)
|
|
245
|
+
|
|
246
|
+
def __setitem__(self, key, value):
|
|
247
|
+
setattr(self, key, value)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
0 5 -4 1 0 0 -0.00010 -0.00010 -0.00010 0X1.655 0.00023
|
|
2
|
+
0 5 -2 -1 0 0 -0.00049 -0.00049 -0.00049 0X3.455 0.00116
|
|
3
|
+
0 5 -2 -1 1 0 -0.00020 -0.00020 -0.00020 0X3.465 0.00048
|
|
4
|
+
0 5 0 -3 0 0 -0.00019 -0.00019 -0.00019 0X5.255 0.00045
|
|
5
|
+
0 5 0 -3 1 0 -0.00008 -0.00008 -0.00008 0X5.265 0.00019
|
|
6
|
+
0 6 -4 0 0 0 -0.00005 -0.00005 -0.00005 0E1.555 0.00012
|
|
7
|
+
0 6 -2 0 0 0 -0.00008 -0.00008 -0.00008 0E3.555 0.00019
|
|
8
|
+
1 -5 0 4 0 0 -0.00008 -0.00008 -0.00008 105.955 0.00011
|
|
9
|
+
1 -5 2 2 0 0 -0.00032 -0.00032 -0.00032 107.755 0.00046
|
|
10
|
+
1 -5 4 0 0 0 -0.00019 -0.00019 -0.00019 109.555 0.00028
|
|
11
|
+
1 5 -2 0 0 0 0.00035 0.00035 0.00035 1X3.555 -0.00050
|
|
12
|
+
1 5 -2 0 1 0 0.00022 0.00022 0.00022 1X3.565 -0.00032
|
|
13
|
+
1 5 0 -2 0 0 0.00029 0.00029 0.00029 1X5.355 -0.00041
|
|
14
|
+
1 5 0 -2 1 0 0.00019 0.00019 0.00019 1X5.365 -0.00027
|
|
15
|
+
1 6 -2 -1 0 0 0.00008 0.00008 0.00008 1E3.455 -0.00012
|
|
16
|
+
2 -5 2 3 0 0 0.00010 0.00010 0.00010 207.855 0.00015
|
|
17
|
+
2 -5 4 1 0 0 0.00013 0.00013 0.00013 209.655 0.00018
|
|
18
|
+
2 5 -2 -1 0 0 0.00012 0.00012 0.00012 2X3.455 0.00017
|
|
19
|
+
2 5 0 -1 0 0 0.00022 0.00022 0.00022 2X5.455 0.00032
|
|
20
|
+
2 5 0 -1 1 0 0.00019 0.00019 0.00019 2X5.465 0.00028
|
|
21
|
+
3 -3 2 1 0 0 0.00011 0.00011 0.00011 327.655 -0.00017
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
u"""
|
|
3
3
|
constituents.py
|
|
4
|
-
Written by Tyler Sutterley (
|
|
4
|
+
Written by Tyler Sutterley (02/2025)
|
|
5
5
|
Basic tide model constituent class
|
|
6
6
|
|
|
7
7
|
PYTHON DEPENDENCIES:
|
|
@@ -10,6 +10,7 @@ PYTHON DEPENDENCIES:
|
|
|
10
10
|
https://numpy.org/doc/stable/user/numpy-for-matlab-users.html
|
|
11
11
|
|
|
12
12
|
UPDATE HISTORY:
|
|
13
|
+
Updated 02/2025: add RHO to rho1 to known mappable constituents
|
|
13
14
|
Updated 11/2024: added property for Extended Doodson numbers
|
|
14
15
|
Updated 10/2024: added property for the shape of constituent fields
|
|
15
16
|
Updated 09/2024: add more known constituents to string parser function
|
|
@@ -241,13 +242,14 @@ class constituents:
|
|
|
241
242
|
# include negative look-behind and look-ahead for complex cases
|
|
242
243
|
cindex = [r'(?<!s)sa','ssa','mm','msf',r'mt(?!m)(?!ide)','mf','alpha1',
|
|
243
244
|
'2q1','sigma1',r'(?<!2)q1','rho1',r'(?<!rh)(?<!o)(?<!s)o1','tau1',
|
|
244
|
-
'm1','chi1','pi1','p1','s1','k1','psi1','phi1','beta1',
|
|
245
|
-
'oo1','2n2','mu2',r'(?<!2)n2','nu2',
|
|
246
|
-
|
|
247
|
-
'
|
|
248
|
-
'
|
|
249
|
-
|
|
250
|
-
r'(?<!m)n4','eps2','ups1',
|
|
245
|
+
'm1','chi1','pi1',r'(?<!al)p1','s1','k1','psi1','phi1','beta1',
|
|
246
|
+
'theta1','j1','oo1','2n2','mu2',r'(?<!2)n2','nu2',
|
|
247
|
+
r'(?<!2s)(?<!l)(?<!la)(?<!ga)m2(?!a)(?!b)','m2a','m2b','lambda2',
|
|
248
|
+
r'(?<!de)l2',r'(?<!be)t2',r'(?<!mn)(?<!mk)(?<!ep)s2(?!0)','alpha2',
|
|
249
|
+
'beta2','delta2','gamma2','r2','k2',r'(?<!b)eta2','mns2','2sm2',
|
|
250
|
+
'm3','mk3','s3','mn4','m4','ms4','mk4','so1',r'(?<!m)s4','s5','m6',
|
|
251
|
+
's6','s7','s8','m8','mks2','msqm','mtm',r'(?<!m)n4','eps2','ups1',
|
|
252
|
+
'z0','node']
|
|
251
253
|
# compile regular expression
|
|
252
254
|
# adding GOT prime nomenclature for 3rd degree constituents
|
|
253
255
|
rx = re.compile(r'(' + '|'.join(cindex) + r')(\')?', re.IGNORECASE)
|
|
@@ -256,10 +258,12 @@ class constituents:
|
|
|
256
258
|
return "".join(rx.findall(constituent)[0]).lower()
|
|
257
259
|
# known remapped cases
|
|
258
260
|
mapping = [('2n','2n2'), ('alp1', 'alpha1'), ('alp2', 'alpha2'),
|
|
259
|
-
('bet1', 'beta1'), ('bet2', 'beta2'), ('
|
|
260
|
-
('
|
|
261
|
-
('la2','lambda2'), ('lam2','lambda2'),
|
|
262
|
-
('
|
|
261
|
+
('bet1', 'beta1'), ('bet2', 'beta2'), ('del2', 'delta2'),
|
|
262
|
+
('e2','eps2'), ('ep2','eps2'), ('gam2', 'gamma2'),
|
|
263
|
+
('la2','lambda2'), ('lam2','lambda2'), ('lm2','lambda2'),
|
|
264
|
+
('msq', 'msqm'), ('omega0', 'node'), ('om0', 'node'),
|
|
265
|
+
('rho', 'rho1'), ('sig1','sigma1'),
|
|
266
|
+
('the', 'theta1'), ('the1', 'theta1')]
|
|
263
267
|
# iterate over known remapped cases
|
|
264
268
|
for m in mapping:
|
|
265
269
|
# check if tide model is a remapped case
|