pyTMD 2.2.7__tar.gz → 2.2.9__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.7 → pytmd-2.2.9}/MANIFEST.in +1 -0
- pytmd-2.2.9/PKG-INFO +227 -0
- pytmd-2.2.9/README.md +131 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/__init__.py +6 -8
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/arguments.py +82 -35
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/astro.py +56 -2
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/compute.py +215 -32
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/crs.py +52 -24
- pytmd-2.2.9/pyTMD/data/ct1971_tab6.txt +31 -0
- pytmd-2.2.9/pyTMD/data/cte1973_tab.txt +485 -0
- pytmd-2.2.9/pyTMD/data/d1921_tab.txt +21 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/database.json +364 -21
- pytmd-2.2.9/pyTMD/data/hw1995_tab.txt +12584 -0
- pytmd-2.2.9/pyTMD/data/t1987_tab.txt +1201 -0
- pytmd-2.2.9/pyTMD/data/w1990_tab.txt +487 -0
- pytmd-2.2.9/pyTMD/datasets/__init__.py +16 -0
- pytmd-2.2.7/pyTMD/scripts/arcticdata_tides.py → pytmd-2.2.9/pyTMD/datasets/fetch_arcticdata.py +42 -21
- pytmd-2.2.7/pyTMD/scripts/aviso_fes_tides.py → pytmd-2.2.9/pyTMD/datasets/fetch_aviso_fes.py +207 -87
- pytmd-2.2.7/pyTMD/scripts/gsfc_got_tides.py → pytmd-2.2.9/pyTMD/datasets/fetch_gsfc_got.py +73 -33
- pytmd-2.2.9/pyTMD/datasets/fetch_test_data.py +187 -0
- pytmd-2.2.7/pyTMD/scripts/reduce_OTIS_files.py → pytmd-2.2.9/pyTMD/datasets/reduce_otis.py +70 -46
- {pytmd-2.2.7/pyTMD/scripts → pytmd-2.2.9/pyTMD/datasets}/verify_box_tpxo.py +31 -16
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/interpolate.py +282 -136
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/ATLAS.py +8 -1
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/FES.py +24 -21
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/GOT.py +20 -20
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/OTIS.py +848 -290
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/__init__.py +7 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/constituents.py +105 -9
- pytmd-2.2.9/pyTMD/io/dataset.py +229 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/model.py +76 -6
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/math.py +18 -7
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/predict.py +153 -102
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/solve/constants.py +43 -5
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/tools.py +3 -2
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/utilities.py +39 -6
- pytmd-2.2.9/pyTMD.egg-info/PKG-INFO +227 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD.egg-info/SOURCES.txt +13 -9
- pytmd-2.2.9/pyTMD.egg-info/entry_points.txt +11 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD.egg-info/requires.txt +16 -3
- {pytmd-2.2.7 → pytmd-2.2.9}/pyproject.toml +89 -23
- pytmd-2.2.7/PKG-INFO +0 -242
- pytmd-2.2.7/README.rst +0 -158
- pytmd-2.2.7/pyTMD/compute_tide_corrections.py +0 -174
- pytmd-2.2.7/pyTMD/data/ce1973_tab1.txt +0 -385
- pytmd-2.2.7/pyTMD/data/ct1971_tab5.txt +0 -99
- pytmd-2.2.7/pyTMD/data/ct1971_tab6.txt +0 -31
- pytmd-2.2.7/pyTMD/data/d1921_tab.txt +0 -21
- pytmd-2.2.7/pyTMD.egg-info/PKG-INFO +0 -242
- pytmd-2.2.7/pyTMD.egg-info/entry_points.txt +0 -6
- {pytmd-2.2.7 → pytmd-2.2.9}/LICENSE +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/doodson.json +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/opoleloadcoefcmcor.txt.gz +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/tab5.2e.txt +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/tab5.3a.txt +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/data/tab5.3b.txt +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/ellipse.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/IERS.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/io/NOAA.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/solve/__init__.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/spatial.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD/version.py +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD.egg-info/dependency_links.txt +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/pyTMD.egg-info/top_level.txt +0 -0
- {pytmd-2.2.7 → pytmd-2.2.9}/setup.cfg +0 -0
pytmd-2.2.9/PKG-INFO
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyTMD
|
|
3
|
+
Version: 2.2.9
|
|
4
|
+
Summary: Python-based tidal prediction software for estimating ocean, load, solid Earth and pole tides
|
|
5
|
+
Author: Tyler Sutterley
|
|
6
|
+
Author-email: tsutterl@uw.edu
|
|
7
|
+
Maintainer: pyTMD contributors
|
|
8
|
+
License: MIT License
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2017 Tyler C Sutterley
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
|
29
|
+
|
|
30
|
+
Project-URL: Homepage, https://pytmd.readthedocs.io
|
|
31
|
+
Project-URL: Documentation, https://pytmd.readthedocs.io
|
|
32
|
+
Project-URL: Repository, https://github.com/pyTMD/pyTMD
|
|
33
|
+
Project-URL: Issues, https://github.com/pyTMD/pyTMD/issues
|
|
34
|
+
Keywords: Ocean Tides,Load Tides,Pole Tides,Solid Earth Tides,Tidal Prediction
|
|
35
|
+
Classifier: Development Status :: 3 - Alpha
|
|
36
|
+
Classifier: Intended Audience :: Science/Research
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: OS Independent
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
44
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
45
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
46
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
47
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
48
|
+
Classifier: Topic :: Scientific/Engineering :: Oceanography
|
|
49
|
+
Requires-Python: ~=3.6
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
License-File: LICENSE
|
|
52
|
+
Requires-Dist: lxml
|
|
53
|
+
Requires-Dist: netCDF4
|
|
54
|
+
Requires-Dist: numpy
|
|
55
|
+
Requires-Dist: platformdirs
|
|
56
|
+
Requires-Dist: pyproj>=2.5.0
|
|
57
|
+
Requires-Dist: python-dateutil
|
|
58
|
+
Requires-Dist: scipy>=1.10.1
|
|
59
|
+
Requires-Dist: timescale>=0.0.8
|
|
60
|
+
Provides-Extra: doc
|
|
61
|
+
Requires-Dist: docutils; extra == "doc"
|
|
62
|
+
Requires-Dist: graphviz; extra == "doc"
|
|
63
|
+
Requires-Dist: myst-nb; extra == "doc"
|
|
64
|
+
Requires-Dist: numpydoc; extra == "doc"
|
|
65
|
+
Requires-Dist: sphinx; extra == "doc"
|
|
66
|
+
Requires-Dist: sphinx-argparse>=0.4; extra == "doc"
|
|
67
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == "doc"
|
|
68
|
+
Requires-Dist: sphinx-design; extra == "doc"
|
|
69
|
+
Requires-Dist: sphinx_rtd_theme; extra == "doc"
|
|
70
|
+
Provides-Extra: all
|
|
71
|
+
Requires-Dist: cartopy; extra == "all"
|
|
72
|
+
Requires-Dist: ipyleaflet; extra == "all"
|
|
73
|
+
Requires-Dist: ipywidgets; extra == "all"
|
|
74
|
+
Requires-Dist: jplephem; extra == "all"
|
|
75
|
+
Requires-Dist: jupyterlab; extra == "all"
|
|
76
|
+
Requires-Dist: matplotlib; extra == "all"
|
|
77
|
+
Requires-Dist: notebook; extra == "all"
|
|
78
|
+
Requires-Dist: pandas; extra == "all"
|
|
79
|
+
Requires-Dist: xarray; extra == "all"
|
|
80
|
+
Provides-Extra: aws
|
|
81
|
+
Requires-Dist: dask; extra == "aws"
|
|
82
|
+
Requires-Dist: geopandas; extra == "aws"
|
|
83
|
+
Requires-Dist: h5netcdf; extra == "aws"
|
|
84
|
+
Requires-Dist: obstore; extra == "aws"
|
|
85
|
+
Requires-Dist: pyarrow; extra == "aws"
|
|
86
|
+
Requires-Dist: s3fs; extra == "aws"
|
|
87
|
+
Requires-Dist: zarr>=3; extra == "aws"
|
|
88
|
+
Provides-Extra: dev
|
|
89
|
+
Requires-Dist: flake8; extra == "dev"
|
|
90
|
+
Requires-Dist: gh; extra == "dev"
|
|
91
|
+
Requires-Dist: oct2py; extra == "dev"
|
|
92
|
+
Requires-Dist: pytest>=4.6; extra == "dev"
|
|
93
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
94
|
+
Requires-Dist: pytest-xdist; extra == "dev"
|
|
95
|
+
Dynamic: license-file
|
|
96
|
+
|
|
97
|
+
# pyTMD
|
|
98
|
+
|
|
99
|
+
[](https://github.com/pyTMD/pyTMD/blob/main/LICENSE)
|
|
100
|
+
[](https://pytmd.readthedocs.io/en/latest/?badge=latest)
|
|
101
|
+
[](https://pypi.python.org/pypi/pyTMD/)
|
|
102
|
+
[](https://anaconda.org/conda-forge/pytmd)
|
|
103
|
+
[](https://github.com/pyTMD/pyTMD/releases/latest)
|
|
104
|
+
[](https://doi.org/10.5281/zenodo.5555395)
|
|
105
|
+
|
|
106
|
+
Python-based tidal prediction software for estimating ocean, load, solid Earth and pole tides
|
|
107
|
+
|
|
108
|
+
For more information: see the documentation at [pytmd.readthedocs.io](https://pytmd.readthedocs.io/)
|
|
109
|
+
|
|
110
|
+
## Installation
|
|
111
|
+
|
|
112
|
+
From PyPI:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python3 -m pip install pyTMD
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
To include all optional dependencies:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
python3 -m pip install pyTMD[all]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Using `conda` or `mamba` from conda-forge:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
conda install -c conda-forge pytmd
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
mamba install -c conda-forge pytmd
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Development version from GitHub:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
python3 -m pip install git+https://github.com/pyTMD/pyTMD.git
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Running with Pixi
|
|
141
|
+
|
|
142
|
+
Alternatively, you can use [Pixi](https://pixi.sh/) for a streamlined workspace environment:
|
|
143
|
+
|
|
144
|
+
1. Install Pixi following the [installation instructions](https://pixi.sh/latest/#installation)
|
|
145
|
+
2. Clone the project repository:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
git clone https://github.com/pyTMD/pyTMD.git
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
3. Move into the `pyTMD` directory
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cd pyTMD
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
4. Install dependencies and start JupyterLab:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pixi run start
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This will automatically create the environment, install all dependencies, and launch JupyterLab in the [notebooks](./doc/source/notebooks/) directory.
|
|
164
|
+
|
|
165
|
+
## Dependencies
|
|
166
|
+
|
|
167
|
+
- [dateutil: powerful extensions to datetime](https://dateutil.readthedocs.io/en/stable/)
|
|
168
|
+
- [lxml: processing XML and HTML in Python](https://pypi.python.org/pypi/lxml)
|
|
169
|
+
- [netCDF4: Python interface to the netCDF C library](https://unidata.github.io/netcdf4-python/)
|
|
170
|
+
- [numpy: Scientific Computing Tools For Python](https://www.numpy.org)
|
|
171
|
+
- [platformdirs: Python module for determining platform-specific directories](https://pypi.org/project/platformdirs/)
|
|
172
|
+
- [pyproj: Python interface to PROJ library](https://pypi.org/project/pyproj/)
|
|
173
|
+
- [scipy: Scientific Tools for Python](https://www.scipy.org/)
|
|
174
|
+
- [timescale: Python tools for time and astronomical calculations](https://pypi.org/project/timescale/)
|
|
175
|
+
|
|
176
|
+
## References
|
|
177
|
+
|
|
178
|
+
> T. C. Sutterley, T. Markus, T. A. Neumann, M. R. van den Broeke, J. M. van Wessem, and S. R. M. Ligtenberg,
|
|
179
|
+
> "Antarctic ice shelf thickness change from multimission lidar mapping", *The Cryosphere*,
|
|
180
|
+
> 13, 1801-1817, (2019). [doi: 10.5194/tc-13-1801-2019](https://doi.org/10.5194/tc-13-1801-2019)
|
|
181
|
+
>
|
|
182
|
+
> L. Padman, M. R. Siegfried, H. A. Fricker,
|
|
183
|
+
> "Ocean Tide Influences on the Antarctic and Greenland Ice Sheets", *Reviews of Geophysics*,
|
|
184
|
+
> 56, 142-184, (2018). [doi: 10.1002/2016RG000546](https://doi.org/10.1002/2016RG000546)
|
|
185
|
+
|
|
186
|
+
## Download
|
|
187
|
+
|
|
188
|
+
The program homepage is:
|
|
189
|
+
<https://github.com/pyTMD/pyTMD>
|
|
190
|
+
|
|
191
|
+
A zip archive of the latest version is available directly at:
|
|
192
|
+
<https://github.com/pyTMD/pyTMD/archive/main.zip>
|
|
193
|
+
|
|
194
|
+
## Alternative Software
|
|
195
|
+
|
|
196
|
+
perth5 from NASA Goddard Space Flight Center:
|
|
197
|
+
<https://codeberg.org/rray/perth5>
|
|
198
|
+
|
|
199
|
+
Matlab Tide Model Driver from Earth & Space Research:
|
|
200
|
+
<https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5>
|
|
201
|
+
|
|
202
|
+
Fortran OSU Tidal Prediction Software:
|
|
203
|
+
<https://www.tpxo.net/otps>
|
|
204
|
+
|
|
205
|
+
## Disclaimer
|
|
206
|
+
|
|
207
|
+
This package includes software developed at NASA Goddard Space Flight Center (GSFC) and the University of Washington Applied Physics Laboratory (UW-APL).
|
|
208
|
+
It is not sponsored or maintained by the Universities Space Research Association (USRA), AVISO or NASA.
|
|
209
|
+
The software is provided here for your convenience but *with no guarantees whatsoever*.
|
|
210
|
+
It should not be used for coastal navigation or any application that may risk life or property.
|
|
211
|
+
|
|
212
|
+
## Contributing
|
|
213
|
+
|
|
214
|
+
This project contains work and contributions from the [scientific community](./CONTRIBUTORS.md).
|
|
215
|
+
If you would like to contribute to the project, please have a look at the [contribution guidelines](./doc/source/getting_started/Contributing.rst), [open issues](https://github.com/pyTMD/pyTMD/issues) and [discussions board](https://github.com/pyTMD/pyTMD/discussions).
|
|
216
|
+
|
|
217
|
+
## Credits
|
|
218
|
+
|
|
219
|
+
The Tidal Model Driver ([TMD](https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5)) Matlab Toolbox was developed by Laurie Padman, Lana Erofeeva and Susan Howard.
|
|
220
|
+
An updated version of the TMD Matlab Toolbox ([TMD3](https://github.com/chadagreene/Tide-Model-Driver)) was developed by Chad Greene.
|
|
221
|
+
The OSU Tidal Inversion Software (OTIS) and OSU Tidal Prediction Software ([OTPS](https://www.tpxo.net/otps)) were developed by Lana Erofeeva and Gary Egbert ([copyright OSU](https://www.tpxo.net/tpxo-products-and-registration), licensed for non-commercial use).
|
|
222
|
+
The NASA Goddard Space Flight Center (GSFC) PREdict Tidal Heights (PERTH3) software was developed by Richard Ray and Remko Scharroo.
|
|
223
|
+
An updated and more versatile version of the NASA GSFC tidal prediction software ([PERTH5](https://codeberg.org/rray/perth5)) was developed by Richard Ray.
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
The content of this project is licensed under the [Creative Commons Attribution 4.0 Attribution license](https://creativecommons.org/licenses/by/4.0/) and the source code is licensed under the [MIT license](LICENSE).
|
pytmd-2.2.9/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# pyTMD
|
|
2
|
+
|
|
3
|
+
[](https://github.com/pyTMD/pyTMD/blob/main/LICENSE)
|
|
4
|
+
[](https://pytmd.readthedocs.io/en/latest/?badge=latest)
|
|
5
|
+
[](https://pypi.python.org/pypi/pyTMD/)
|
|
6
|
+
[](https://anaconda.org/conda-forge/pytmd)
|
|
7
|
+
[](https://github.com/pyTMD/pyTMD/releases/latest)
|
|
8
|
+
[](https://doi.org/10.5281/zenodo.5555395)
|
|
9
|
+
|
|
10
|
+
Python-based tidal prediction software for estimating ocean, load, solid Earth and pole tides
|
|
11
|
+
|
|
12
|
+
For more information: see the documentation at [pytmd.readthedocs.io](https://pytmd.readthedocs.io/)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
From PyPI:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
python3 -m pip install pyTMD
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
To include all optional dependencies:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
python3 -m pip install pyTMD[all]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Using `conda` or `mamba` from conda-forge:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
conda install -c conda-forge pytmd
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
mamba install -c conda-forge pytmd
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Development version from GitHub:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
python3 -m pip install git+https://github.com/pyTMD/pyTMD.git
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Running with Pixi
|
|
45
|
+
|
|
46
|
+
Alternatively, you can use [Pixi](https://pixi.sh/) for a streamlined workspace environment:
|
|
47
|
+
|
|
48
|
+
1. Install Pixi following the [installation instructions](https://pixi.sh/latest/#installation)
|
|
49
|
+
2. Clone the project repository:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
git clone https://github.com/pyTMD/pyTMD.git
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
3. Move into the `pyTMD` directory
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd pyTMD
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
4. Install dependencies and start JupyterLab:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pixi run start
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This will automatically create the environment, install all dependencies, and launch JupyterLab in the [notebooks](./doc/source/notebooks/) directory.
|
|
68
|
+
|
|
69
|
+
## Dependencies
|
|
70
|
+
|
|
71
|
+
- [dateutil: powerful extensions to datetime](https://dateutil.readthedocs.io/en/stable/)
|
|
72
|
+
- [lxml: processing XML and HTML in Python](https://pypi.python.org/pypi/lxml)
|
|
73
|
+
- [netCDF4: Python interface to the netCDF C library](https://unidata.github.io/netcdf4-python/)
|
|
74
|
+
- [numpy: Scientific Computing Tools For Python](https://www.numpy.org)
|
|
75
|
+
- [platformdirs: Python module for determining platform-specific directories](https://pypi.org/project/platformdirs/)
|
|
76
|
+
- [pyproj: Python interface to PROJ library](https://pypi.org/project/pyproj/)
|
|
77
|
+
- [scipy: Scientific Tools for Python](https://www.scipy.org/)
|
|
78
|
+
- [timescale: Python tools for time and astronomical calculations](https://pypi.org/project/timescale/)
|
|
79
|
+
|
|
80
|
+
## References
|
|
81
|
+
|
|
82
|
+
> T. C. Sutterley, T. Markus, T. A. Neumann, M. R. van den Broeke, J. M. van Wessem, and S. R. M. Ligtenberg,
|
|
83
|
+
> "Antarctic ice shelf thickness change from multimission lidar mapping", *The Cryosphere*,
|
|
84
|
+
> 13, 1801-1817, (2019). [doi: 10.5194/tc-13-1801-2019](https://doi.org/10.5194/tc-13-1801-2019)
|
|
85
|
+
>
|
|
86
|
+
> L. Padman, M. R. Siegfried, H. A. Fricker,
|
|
87
|
+
> "Ocean Tide Influences on the Antarctic and Greenland Ice Sheets", *Reviews of Geophysics*,
|
|
88
|
+
> 56, 142-184, (2018). [doi: 10.1002/2016RG000546](https://doi.org/10.1002/2016RG000546)
|
|
89
|
+
|
|
90
|
+
## Download
|
|
91
|
+
|
|
92
|
+
The program homepage is:
|
|
93
|
+
<https://github.com/pyTMD/pyTMD>
|
|
94
|
+
|
|
95
|
+
A zip archive of the latest version is available directly at:
|
|
96
|
+
<https://github.com/pyTMD/pyTMD/archive/main.zip>
|
|
97
|
+
|
|
98
|
+
## Alternative Software
|
|
99
|
+
|
|
100
|
+
perth5 from NASA Goddard Space Flight Center:
|
|
101
|
+
<https://codeberg.org/rray/perth5>
|
|
102
|
+
|
|
103
|
+
Matlab Tide Model Driver from Earth & Space Research:
|
|
104
|
+
<https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5>
|
|
105
|
+
|
|
106
|
+
Fortran OSU Tidal Prediction Software:
|
|
107
|
+
<https://www.tpxo.net/otps>
|
|
108
|
+
|
|
109
|
+
## Disclaimer
|
|
110
|
+
|
|
111
|
+
This package includes software developed at NASA Goddard Space Flight Center (GSFC) and the University of Washington Applied Physics Laboratory (UW-APL).
|
|
112
|
+
It is not sponsored or maintained by the Universities Space Research Association (USRA), AVISO or NASA.
|
|
113
|
+
The software is provided here for your convenience but *with no guarantees whatsoever*.
|
|
114
|
+
It should not be used for coastal navigation or any application that may risk life or property.
|
|
115
|
+
|
|
116
|
+
## Contributing
|
|
117
|
+
|
|
118
|
+
This project contains work and contributions from the [scientific community](./CONTRIBUTORS.md).
|
|
119
|
+
If you would like to contribute to the project, please have a look at the [contribution guidelines](./doc/source/getting_started/Contributing.rst), [open issues](https://github.com/pyTMD/pyTMD/issues) and [discussions board](https://github.com/pyTMD/pyTMD/discussions).
|
|
120
|
+
|
|
121
|
+
## Credits
|
|
122
|
+
|
|
123
|
+
The Tidal Model Driver ([TMD](https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5)) Matlab Toolbox was developed by Laurie Padman, Lana Erofeeva and Susan Howard.
|
|
124
|
+
An updated version of the TMD Matlab Toolbox ([TMD3](https://github.com/chadagreene/Tide-Model-Driver)) was developed by Chad Greene.
|
|
125
|
+
The OSU Tidal Inversion Software (OTIS) and OSU Tidal Prediction Software ([OTPS](https://www.tpxo.net/otps)) were developed by Lana Erofeeva and Gary Egbert ([copyright OSU](https://www.tpxo.net/tpxo-products-and-registration), licensed for non-commercial use).
|
|
126
|
+
The NASA Goddard Space Flight Center (GSFC) PREdict Tidal Heights (PERTH3) software was developed by Richard Ray and Remko Scharroo.
|
|
127
|
+
An updated and more versatile version of the NASA GSFC tidal prediction software ([PERTH5](https://codeberg.org/rray/perth5)) was developed by Richard Ray.
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
The content of this project is licensed under the [Creative Commons Attribution 4.0 Attribution license](https://creativecommons.org/licenses/by/4.0/) and the source code is licensed under the [MIT license](LICENSE).
|
|
@@ -22,19 +22,17 @@ import pyTMD.spatial
|
|
|
22
22
|
import pyTMD.tools
|
|
23
23
|
import pyTMD.utilities
|
|
24
24
|
import pyTMD.version
|
|
25
|
+
from pyTMD import datasets
|
|
25
26
|
from pyTMD import io
|
|
26
27
|
from pyTMD import solve
|
|
27
28
|
from pyTMD.crs import crs
|
|
28
29
|
|
|
29
30
|
# Deprecated functions
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
compute_OPT_corrections,
|
|
36
|
-
compute_SET_corrections,
|
|
37
|
-
)
|
|
31
|
+
def compute_tide_corrections(*args, **kwargs):
|
|
32
|
+
"""Wrapper function to compute tide corrections
|
|
33
|
+
Deprecated, use :func:`pyTMD.compute.tide_elevations` instead
|
|
34
|
+
"""
|
|
35
|
+
return pyTMD.compute.tide_elevations(*args, **kwargs)
|
|
38
36
|
|
|
39
37
|
# get version information
|
|
40
38
|
__version__ = pyTMD.version.version
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
u"""
|
|
3
3
|
arguments.py
|
|
4
|
-
Written by Tyler Sutterley (
|
|
4
|
+
Written by Tyler Sutterley (09/2025)
|
|
5
5
|
Calculates the nodal corrections for tidal constituents
|
|
6
6
|
Modification of ARGUMENTS fortran subroutine by Richard Ray 03/1999
|
|
7
7
|
|
|
@@ -39,6 +39,8 @@ REFERENCES:
|
|
|
39
39
|
Ocean Tides", Journal of Atmospheric and Oceanic Technology, (2002).
|
|
40
40
|
|
|
41
41
|
UPDATE HISTORY:
|
|
42
|
+
Updated 09/2025: added spherical harmonic degree to tide potential tables
|
|
43
|
+
added IERS Conventions references for Love number calculations
|
|
42
44
|
Updated 08/2025: add Cartwright and Tayler table with radiational tides
|
|
43
45
|
make frequency function a wrapper around one that calculates using
|
|
44
46
|
Doodson coefficients (Cartwright numbers)
|
|
@@ -1773,6 +1775,8 @@ def _frequency(
|
|
|
1773
1775
|
- ``'Meeus'``
|
|
1774
1776
|
- ``'ASTRO5'``
|
|
1775
1777
|
- ``'IERS'``
|
|
1778
|
+
include_planets: bool, default False
|
|
1779
|
+
Include planetary terms in the frequency calculation
|
|
1776
1780
|
|
|
1777
1781
|
Returns
|
|
1778
1782
|
-------
|
|
@@ -1781,6 +1785,7 @@ def _frequency(
|
|
|
1781
1785
|
"""
|
|
1782
1786
|
# set default keyword arguments
|
|
1783
1787
|
kwargs.setdefault('method', 'Cartwright')
|
|
1788
|
+
kwargs.setdefault('include_planets', False)
|
|
1784
1789
|
# Modified Julian Dates at J2000
|
|
1785
1790
|
MJD = np.array([51544.5, 51544.55])
|
|
1786
1791
|
# time interval in seconds
|
|
@@ -1799,7 +1804,13 @@ def _frequency(
|
|
|
1799
1804
|
k = 90.0 + np.zeros((nt))
|
|
1800
1805
|
|
|
1801
1806
|
# determine equilibrium arguments
|
|
1802
|
-
|
|
1807
|
+
if kwargs['include_planets']:
|
|
1808
|
+
lm, lv, la, lj, ls = pyTMD.astro.planetary_longitudes(MJD)
|
|
1809
|
+
fargs = np.c_[tau, s, h, p, n, pp, k, lm, lv, la, lj, ls]
|
|
1810
|
+
else:
|
|
1811
|
+
fargs = np.c_[tau, s, h, p, n, pp, k]
|
|
1812
|
+
|
|
1813
|
+
# calculate the rates of change of the fundamental arguments
|
|
1803
1814
|
rates = (fargs[1,:] - fargs[0,:])/deltat
|
|
1804
1815
|
fd = np.dot(rates, coef)
|
|
1805
1816
|
# convert to radians per second
|
|
@@ -1919,7 +1930,7 @@ def _complex_love_numbers(
|
|
|
1919
1930
|
omega: np.ndarray
|
|
1920
1931
|
angular frequency (radians per second)
|
|
1921
1932
|
kwargs: dict
|
|
1922
|
-
additional keyword arguments for
|
|
1933
|
+
additional keyword arguments for Love number calculation
|
|
1923
1934
|
|
|
1924
1935
|
Returns
|
|
1925
1936
|
-------
|
|
@@ -1930,20 +1941,24 @@ def _complex_love_numbers(
|
|
|
1930
1941
|
l2: complex
|
|
1931
1942
|
Degree-2 Love (Shida) number of horizontal displacement
|
|
1932
1943
|
"""
|
|
1933
|
-
#
|
|
1944
|
+
# number of sidereal days per solar day
|
|
1934
1945
|
sidereal_ratio = 1.002737909
|
|
1935
|
-
# number of seconds in a sidereal day (
|
|
1946
|
+
# number of seconds in a sidereal day (approximately 86164.1)
|
|
1936
1947
|
sidereal_day = 86400.0/sidereal_ratio
|
|
1937
1948
|
# frequency in cycles per sidereal day
|
|
1938
1949
|
f = omega*sidereal_day/(2.0*np.pi)
|
|
1939
1950
|
# Love numbers for different frequency bands
|
|
1940
1951
|
if (omega == 0.0):
|
|
1941
|
-
# use real-valued body tide
|
|
1952
|
+
# use real-valued body tide Love numbers for the permanent tide
|
|
1953
|
+
# to prevent singularities in frequency-dependent model
|
|
1942
1954
|
h2, k2, l2 = _love_numbers(omega, **kwargs)
|
|
1943
1955
|
elif (omega > 1e-4):
|
|
1944
1956
|
# in-phase and out-of-phase components for the semi-diurnal band
|
|
1945
|
-
|
|
1957
|
+
# table 7.3a (IERS conventions 2010)
|
|
1958
|
+
h2 = 0.6078 - 0.0025j
|
|
1959
|
+
# table 6.5c (IERS conventions 2010)
|
|
1946
1960
|
k2 = 0.30102 - 0.0013j
|
|
1961
|
+
# table 7.3a (IERS conventions 2010)
|
|
1947
1962
|
l2 = 0.0847 - 0.0007j
|
|
1948
1963
|
elif (omega < 2e-5):
|
|
1949
1964
|
# compute in-phase and out-of-phase components for the long period band
|
|
@@ -1953,9 +1968,12 @@ def _complex_love_numbers(
|
|
|
1953
1968
|
fm = sidereal_day/200.0
|
|
1954
1969
|
factor = np.tan(alpha*np.pi/2.0)**(-1)
|
|
1955
1970
|
anelasticity_model = factor*(1.0 - (fm/f)**alpha) + 1j*(fm/f)**alpha
|
|
1956
|
-
# model for the variation of
|
|
1971
|
+
# model for the variation of Love numbers across the zonal tide band
|
|
1972
|
+
# equation 7.4a (IERS conventions 2010)
|
|
1957
1973
|
h2 = 0.5998 - 9.96e-4*anelasticity_model
|
|
1974
|
+
# equation 6.12 (IERS conventions 2010)
|
|
1958
1975
|
k2 = 0.29525 - 5.796e-4*anelasticity_model
|
|
1976
|
+
# equation 7.4b (IERS conventions 2010)
|
|
1959
1977
|
l2 = 0.0831 - 3.01e-4*anelasticity_model
|
|
1960
1978
|
else:
|
|
1961
1979
|
# in-phase and out-of-phase components for the diurnal band
|
|
@@ -1971,50 +1989,58 @@ def _complex_love_numbers(
|
|
|
1971
1989
|
sigma[2] = 1.0023181 + 0.000025j
|
|
1972
1990
|
# prograde free core nutation
|
|
1973
1991
|
sigma[3] = 0.999026 + 0.000780j
|
|
1974
|
-
# frequency dependence of Love number h2
|
|
1992
|
+
# frequency dependence of Love number h2 (vertical)
|
|
1993
|
+
# table 7.1 (IERS conventions 2010)
|
|
1975
1994
|
H2 = np.zeros((4), dtype=np.complex128)
|
|
1976
1995
|
H2[0] = 0.60671 - 0.242e-2j
|
|
1977
1996
|
H2[1] = -0.15777e-2 - 0.7630e-4j
|
|
1978
1997
|
H2[2] = 0.18053e-3 - 0.6292e-5j
|
|
1979
1998
|
H2[3] = -0.18616e-5 + 0.1379e-6j
|
|
1980
|
-
# frequency dependence of Love number k2
|
|
1999
|
+
# frequency dependence of Love number k2 (potential)
|
|
2000
|
+
# table 6.4 (IERS conventions 2010)
|
|
1981
2001
|
K2 = np.zeros((4), dtype=np.complex128)
|
|
1982
2002
|
K2[0] = 0.29954 - 0.1412e-2j
|
|
1983
2003
|
K2[1] = -0.77896e-3 - 0.3711e-4j
|
|
1984
2004
|
K2[2] = 0.90963e-4 - 0.2963e-5j
|
|
1985
2005
|
K2[3] = -0.11416e-5 + 0.5325e-7j
|
|
1986
|
-
# frequency dependence of Love number l2
|
|
2006
|
+
# frequency dependence of Love number l2 (horizontal)
|
|
2007
|
+
# table 7.1 (IERS conventions 2010)
|
|
1987
2008
|
L2 = np.zeros((4), dtype=np.complex128)
|
|
1988
2009
|
L2[0] = 0.84963e-1 - 0.7395e-3j
|
|
1989
|
-
L2[1] = -0.22107e-3 - 0.
|
|
1990
|
-
L2[2] = 0.54710e-5 - 0.2990e-6j
|
|
2010
|
+
L2[1] = -0.22107e-3 - 0.9646e-5j
|
|
2011
|
+
L2[2] = -0.54710e-5 - 0.2990e-6j
|
|
1991
2012
|
L2[3] = -0.29904e-7 - 0.7717e-8j
|
|
1992
|
-
# estimate the complex Love
|
|
1993
|
-
# equation 6.9
|
|
2013
|
+
# estimate the complex Love numbers for diurnal tides
|
|
2014
|
+
# equation 6.9 (IERS conventions 2010)
|
|
1994
2015
|
h2 = np.sum(H2/(f - sigma))
|
|
1995
2016
|
k2 = np.sum(K2/(f - sigma))
|
|
1996
2017
|
l2 = np.sum(L2/(f - sigma))
|
|
1997
2018
|
|
|
1998
2019
|
# return the Love numbers as a complex number
|
|
2020
|
+
# to include the in-phase and out-of-phase components
|
|
1999
2021
|
return np.array([h2, k2, l2], dtype=np.complex128)
|
|
2000
2022
|
|
|
2001
2023
|
# Doodson (1921) table with values missing from Cartwright tables
|
|
2002
2024
|
# Hs1: amplitude for epoch span 1 (1900 epoch)
|
|
2003
2025
|
_d1921_table = get_data_path(['data','d1921_tab.txt'])
|
|
2004
2026
|
# Cartwright and Tayler (1971) table with 3rd-degree values
|
|
2005
|
-
# Hs1: amplitude for epoch span 1 (1861-09-21 to 1879-09-22)
|
|
2006
|
-
# Hs2: amplitude for epoch span 2 (1915-05-16 to 1933-05-22)
|
|
2007
|
-
# Hs3: amplitude for epoch span 2 (1951-05-23 to 1969-05-22)
|
|
2008
|
-
_ct1971_table_5 = get_data_path(['data','ct1971_tab5.txt'])
|
|
2009
2027
|
# Cartwright and Edden (1973) table with updated values
|
|
2010
|
-
|
|
2028
|
+
_cte1973_table = get_data_path(['data','cte1973_tab.txt'])
|
|
2011
2029
|
# Cartwright and Tayler (1971) table with radiational tides
|
|
2012
|
-
# Hs1: amplitude for epoch span 1 (1900 epoch)
|
|
2013
2030
|
_ct1971_table_6 = get_data_path(['data','ct1971_tab6.txt'])
|
|
2031
|
+
# Hartmann and Wenzel (1995) tidal potential catalog
|
|
2032
|
+
_hw1995_table = get_data_path(['data','hw1995_tab.txt'])
|
|
2033
|
+
# Tamura (1987) tidal potential catalog
|
|
2034
|
+
_t1987_table = get_data_path(['data','t1987_tab.txt'])
|
|
2035
|
+
# Woodworth (1990) tables with updated and 3rd-degree values
|
|
2036
|
+
_w1990_table = get_data_path(['data','w1990_tab.txt'])
|
|
2014
2037
|
|
|
2015
2038
|
def _parse_tide_potential_table(
|
|
2016
2039
|
table: str | pathlib.Path,
|
|
2017
|
-
|
|
2040
|
+
skiprows: int = 1,
|
|
2041
|
+
columns: int = 1,
|
|
2042
|
+
include_degree: bool = True,
|
|
2043
|
+
include_planets: bool = False
|
|
2018
2044
|
):
|
|
2019
2045
|
"""Parse tables of tide-generating potential
|
|
2020
2046
|
|
|
@@ -2022,12 +2048,18 @@ def _parse_tide_potential_table(
|
|
|
2022
2048
|
----------
|
|
2023
2049
|
table: str or pathlib.Path
|
|
2024
2050
|
table of tide-generating potentials
|
|
2025
|
-
|
|
2051
|
+
skiprows: int, default 1
|
|
2052
|
+
number of header rows to skip in the table
|
|
2053
|
+
columns: int, default 1
|
|
2026
2054
|
number of amplitude columns in the table
|
|
2055
|
+
include_degree: bool, default True
|
|
2056
|
+
table includes spherical harmonic degree
|
|
2057
|
+
include_planets: bool, default False
|
|
2058
|
+
table includes coefficients for mean longitudes of planets
|
|
2027
2059
|
|
|
2028
2060
|
Returns
|
|
2029
2061
|
-------
|
|
2030
|
-
CTE:
|
|
2062
|
+
CTE: np.ndarray
|
|
2031
2063
|
Cartwright-Tayler-Edden table values
|
|
2032
2064
|
"""
|
|
2033
2065
|
# verify table path
|
|
@@ -2035,15 +2067,32 @@ def _parse_tide_potential_table(
|
|
|
2035
2067
|
with table.open(mode='r', encoding='utf8') as f:
|
|
2036
2068
|
file_contents = f.readlines()
|
|
2037
2069
|
# number of lines in the file
|
|
2038
|
-
file_lines = len(file_contents)
|
|
2039
|
-
#
|
|
2070
|
+
file_lines = len(file_contents) - int(skiprows)
|
|
2071
|
+
# names: names of the columns in the table
|
|
2072
|
+
# formats: data types for each column in the table
|
|
2073
|
+
names = []
|
|
2074
|
+
formats = []
|
|
2075
|
+
# l: spherical harmonic degree
|
|
2076
|
+
if include_degree:
|
|
2077
|
+
names.append('l')
|
|
2078
|
+
formats.append('i')
|
|
2079
|
+
# tau: spherical harmonic dependence (order)
|
|
2040
2080
|
# s: coefficient for mean longitude of moon
|
|
2041
2081
|
# h: coefficient for mean longitude of sun
|
|
2042
2082
|
# p: coefficient for mean longitude of lunar perigee
|
|
2043
2083
|
# n: coefficient for mean longitude of ascending lunar node
|
|
2044
2084
|
# pp: coefficient for mean longitude of solar perigee
|
|
2045
|
-
names
|
|
2046
|
-
formats
|
|
2085
|
+
names.extend(['tau','s','h','p','n','pp'])
|
|
2086
|
+
formats.extend(['i','i','i','i','i','i'])
|
|
2087
|
+
# lme: coefficient for mean longitude of Mercury
|
|
2088
|
+
# lve: coefficient for mean longitude of Venus
|
|
2089
|
+
# lma: coefficient for mean longitude of Mars
|
|
2090
|
+
# lju: coefficient for mean longitude of Jupiter
|
|
2091
|
+
# lsa: coefficient for mean longitude of Saturn
|
|
2092
|
+
if include_planets:
|
|
2093
|
+
names.extend(['lme','lve','lma','lju','lsa'])
|
|
2094
|
+
formats.extend(['i','i','i','i','i'])
|
|
2095
|
+
# tide potential amplitudes (Cartwright and Tayler norm)
|
|
2047
2096
|
for c in range(columns):
|
|
2048
2097
|
# add amplitude columns to names and formats
|
|
2049
2098
|
names.append(f'Hs{c+1}')
|
|
@@ -2052,16 +2101,14 @@ def _parse_tide_potential_table(
|
|
|
2052
2101
|
names.append('DO')
|
|
2053
2102
|
formats.append('U7')
|
|
2054
2103
|
# create a structured numpy dtype for the table
|
|
2055
|
-
# names: names of the columns in the table
|
|
2056
|
-
# formats: data types for each column in the table
|
|
2057
2104
|
dtype = np.dtype({'names':names, 'formats':formats})
|
|
2058
2105
|
CTE = np.zeros((file_lines), dtype=dtype)
|
|
2059
|
-
# number of output columns
|
|
2060
|
-
|
|
2106
|
+
# total number of output columns
|
|
2107
|
+
total_columns = len(names)
|
|
2061
2108
|
# iterate over each line in the file
|
|
2062
|
-
for i,line in enumerate(file_contents):
|
|
2063
|
-
# drop last column with values from Doodson (1921)
|
|
2064
|
-
CTE[i] = np.array(tuple(line.split()[:
|
|
2109
|
+
for i,line in enumerate(file_contents[skiprows:]):
|
|
2110
|
+
# drop last column(s) with values from Doodson (1921)
|
|
2111
|
+
CTE[i] = np.array(tuple(line.split()[:total_columns]), dtype=dtype)
|
|
2065
2112
|
# return the table values
|
|
2066
2113
|
return CTE
|
|
2067
2114
|
|