pyhardisp 0.2.0__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.
- pyhardisp-0.2.0/LICENCE +11 -0
- pyhardisp-0.2.0/LICENSE_IERS.txt +77 -0
- pyhardisp-0.2.0/MANIFEST.in +6 -0
- pyhardisp-0.2.0/PKG-INFO +396 -0
- pyhardisp-0.2.0/README.md +241 -0
- pyhardisp-0.2.0/README_PYTHON_CONVERSION.md +366 -0
- pyhardisp-0.2.0/ocean_loading_nm_s2.csv +11 -0
- pyhardisp-0.2.0/pyhardisp/__init__.py +57 -0
- pyhardisp-0.2.0/pyhardisp/core.py +3403 -0
- pyhardisp-0.2.0/pyhardisp.egg-info/PKG-INFO +396 -0
- pyhardisp-0.2.0/pyhardisp.egg-info/SOURCES.txt +27 -0
- pyhardisp-0.2.0/pyhardisp.egg-info/dependency_links.txt +1 -0
- pyhardisp-0.2.0/pyhardisp.egg-info/requires.txt +6 -0
- pyhardisp-0.2.0/pyhardisp.egg-info/top_level.txt +1 -0
- pyhardisp-0.2.0/pyproject.toml +64 -0
- pyhardisp-0.2.0/setup.cfg +4 -0
- pyhardisp-0.2.0/src/ADMINT.F +448 -0
- pyhardisp-0.2.0/src/ETUTC.F +283 -0
- pyhardisp-0.2.0/src/EVAL.F +196 -0
- pyhardisp-0.2.0/src/HARDISP.F +464 -0
- pyhardisp-0.2.0/src/JULDAT.F +158 -0
- pyhardisp-0.2.0/src/LEAP.F +153 -0
- pyhardisp-0.2.0/src/MDAY.F +154 -0
- pyhardisp-0.2.0/src/RECURS.F +179 -0
- pyhardisp-0.2.0/src/SHELLS.F +209 -0
- pyhardisp-0.2.0/src/SPLINE.F +214 -0
- pyhardisp-0.2.0/src/TDFRPH.F +280 -0
- pyhardisp-0.2.0/src/TOYMD.F +159 -0
- pyhardisp-0.2.0/tests/tests.py +449 -0
pyhardisp-0.2.0/LICENCE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
This software is a Python translation and modification of the
|
|
2
|
+
IERS Conventions software (Copyright © 2008 IERS Conventions Center).
|
|
3
|
+
|
|
4
|
+
The original IERS Conventions Software License is reproduced in
|
|
5
|
+
LICENSE_IERS.txt and governs this derived work.
|
|
6
|
+
|
|
7
|
+
Modifications and Python translation:
|
|
8
|
+
Copyright (C) 2026 [Craig Miller]
|
|
9
|
+
|
|
10
|
+
This project is distributed under the terms of the
|
|
11
|
+
IERS Conventions Software License.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Copyright (C) 2008
|
|
2
|
+
* IERS Conventions Center
|
|
3
|
+
*
|
|
4
|
+
* ==================================
|
|
5
|
+
* IERS Conventions Software License
|
|
6
|
+
* ==================================
|
|
7
|
+
*
|
|
8
|
+
* NOTICE TO USER:
|
|
9
|
+
*
|
|
10
|
+
* BY USING THIS SOFTWARE YOU ACCEPT THE FOLLOWING TERMS AND CONDITIONS
|
|
11
|
+
* WHICH APPLY TO ITS USE.
|
|
12
|
+
*
|
|
13
|
+
* 1. The Software is provided by the IERS Conventions Center ("the
|
|
14
|
+
* Center").
|
|
15
|
+
*
|
|
16
|
+
* 2. Permission is granted to anyone to use the Software for any
|
|
17
|
+
* purpose, including commercial applications, free of charge,
|
|
18
|
+
* subject to the conditions and restrictions listed below.
|
|
19
|
+
*
|
|
20
|
+
* 3. You (the user) may adapt the Software and its algorithms for your
|
|
21
|
+
* own purposes and you may distribute the resulting "derived work"
|
|
22
|
+
* to others, provided that the derived work complies with the
|
|
23
|
+
* following requirements:
|
|
24
|
+
*
|
|
25
|
+
* a) Your work shall be clearly identified so that it cannot be
|
|
26
|
+
* mistaken for IERS Conventions software and that it has been
|
|
27
|
+
* neither distributed by nor endorsed by the Center.
|
|
28
|
+
*
|
|
29
|
+
* b) Your work (including source code) must contain descriptions of
|
|
30
|
+
* how the derived work is based upon and/or differs from the
|
|
31
|
+
* original Software.
|
|
32
|
+
*
|
|
33
|
+
* c) The name(s) of all modified routine(s) that you distribute
|
|
34
|
+
* shall be changed.
|
|
35
|
+
*
|
|
36
|
+
* d) The origin of the IERS Conventions components of your derived
|
|
37
|
+
* work must not be misrepresented; you must not claim that you
|
|
38
|
+
* wrote the original Software.
|
|
39
|
+
*
|
|
40
|
+
* e) The source code must be included for all routine(s) that you
|
|
41
|
+
* distribute. This notice must be reproduced intact in any
|
|
42
|
+
* source distribution.
|
|
43
|
+
*
|
|
44
|
+
* 4. In any published work produced by the user and which includes
|
|
45
|
+
* results achieved by using the Software, you shall acknowledge
|
|
46
|
+
* that the Software was used in obtaining those results.
|
|
47
|
+
*
|
|
48
|
+
* 5. The Software is provided to the user "as is" and the Center makes
|
|
49
|
+
* no warranty as to its use or performance. The Center does not
|
|
50
|
+
* and cannot warrant the performance or results which the user may
|
|
51
|
+
* obtain by using the Software. The Center makes no warranties,
|
|
52
|
+
* express or implied, as to non-infringement of third party rights,
|
|
53
|
+
* merchantability, or fitness for any particular purpose. In no
|
|
54
|
+
* event will the Center be liable to the user for any consequential,
|
|
55
|
+
* incidental, or special damages, including any lost profits or lost
|
|
56
|
+
* savings, even if a Center representative has been advised of such
|
|
57
|
+
* damages, or for any claim by any third party.
|
|
58
|
+
*
|
|
59
|
+
* Correspondence concerning IERS Conventions software should be
|
|
60
|
+
* addressed as follows:
|
|
61
|
+
*
|
|
62
|
+
* Gerard Petit
|
|
63
|
+
* Internet email: gpetit[at]bipm.org
|
|
64
|
+
* Postal address: IERS Conventions Center
|
|
65
|
+
* Time, frequency and gravimetry section, BIPM
|
|
66
|
+
* Pavillon de Breteuil
|
|
67
|
+
* 92312 Sevres FRANCE
|
|
68
|
+
*
|
|
69
|
+
* or
|
|
70
|
+
*
|
|
71
|
+
* Brian Luzum
|
|
72
|
+
* Internet email: brian.luzum[at]usno.navy.mil
|
|
73
|
+
* Postal address: IERS Conventions Center
|
|
74
|
+
* Earth Orientation Department
|
|
75
|
+
* 3450 Massachusetts Ave, NW
|
|
76
|
+
* Washington, DC 20392
|
|
77
|
+
|
pyhardisp-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyhardisp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Ocean loading tidal displacement calculator - Python conversion of IERS HARDISP Fortran program
|
|
5
|
+
Author: IERS Conventions, Python Conversion - Craig Miller
|
|
6
|
+
License-Expression: LicenseRef-IERS
|
|
7
|
+
Project-URL: Homepage, https://github.com/craigmillernz/pyhardisp
|
|
8
|
+
Project-URL: Repository, https://github.com/craigmillernz/pyhardisp
|
|
9
|
+
Keywords: HARDISP,pyhardisp,ocean-loading,tidal,displacement,geodesy,IERS
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Requires-Python: >=3.8
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE_IERS.txt
|
|
24
|
+
Requires-Dist: numpy>=1.19.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
28
|
+
Requires-Dist: ruff; extra == "dev"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# PYHARDISP - Python Module Documentation
|
|
32
|
+
|
|
33
|
+
## Overview
|
|
34
|
+
|
|
35
|
+
This document describes the Python conversion of the **HARDISP** (Harmonic Displacement) Fortran program from the IERS Conventions software collection. The program computes tidal ocean loading displacements at geodetic stations.
|
|
36
|
+
|
|
37
|
+
## What is HARDISP?
|
|
38
|
+
|
|
39
|
+
HARDISP is a scientific program developed by the International Earth Rotation and Reference Systems Service (IERS) for calculating tidal ocean loading effects at geodetic stations. Depending on the coefficients provided by the ocean loading provider, it computes either:
|
|
40
|
+
- **Tidal displacements** (vertical, horizontal components) - when displacement coefficients are provided
|
|
41
|
+
- **Tidal gravity effects** (gravity disturbances) - when gravity-type coefficients are provided
|
|
42
|
+
|
|
43
|
+
These effects are critical corrections for:
|
|
44
|
+
|
|
45
|
+
- GPS and space geodesy
|
|
46
|
+
- Satellite laser ranging (SLR)
|
|
47
|
+
- Very Long Baseline Interferometry (VLBI)
|
|
48
|
+
- Superconducting gravimeter measurements
|
|
49
|
+
- Hydrogeodetic measurements
|
|
50
|
+
|
|
51
|
+
The program is part of the **IERS Conventions 2010** recommendations (Class 1 model) for processing raw space geodetic observations.
|
|
52
|
+
|
|
53
|
+
## Program Purpose
|
|
54
|
+
|
|
55
|
+
Given ocean loading coefficients in BLQ format (from the Bos-Scherneck loading service or equivalent providers), HARDISP computes a time series of tidal ocean loading effects in three components:
|
|
56
|
+
|
|
57
|
+
**Output type depends on the ocean loading provider's coefficients:**
|
|
58
|
+
- **Displacement coefficients**: Returns displacements
|
|
59
|
+
- **dU**: Vertical (radial) displacement (meters)
|
|
60
|
+
- **dS**: South (North-South) displacement (meters)
|
|
61
|
+
- **dW**: West (East-West) displacement (meters)
|
|
62
|
+
|
|
63
|
+
- **Gravity coefficients**: Returns gravity effects
|
|
64
|
+
- **dU**: Vertical gravity effect (nm/s² or equivalent units)
|
|
65
|
+
- **dS**: South gravity tilt effect (nm/s²)
|
|
66
|
+
- **dW**: West gravity tilt effect (nm/s²)
|
|
67
|
+
|
|
68
|
+
The computation uses **342 tidal constituents** derived by spline interpolation of the tidal admittance, providing approximately 0.1% precision.
|
|
69
|
+
|
|
70
|
+
HARDISP processes the coefficients as-is, with no automatic conversions between displacement and gravity types.
|
|
71
|
+
|
|
72
|
+
## Files
|
|
73
|
+
|
|
74
|
+
The Python conversion consists of:
|
|
75
|
+
**core.py** - Main Python module with optimized implementation
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
Original Fortran files (for reference):
|
|
79
|
+
- `HARDISP.F` - Main program
|
|
80
|
+
- `ADMINT.F` - Admittance interpolation
|
|
81
|
+
- `RECURS.F` - Recursive harmonic evaluation
|
|
82
|
+
- `TDFRPH.F` - Tidal frequency and phase calculation
|
|
83
|
+
- `SPLINE.F`, `EVAL.F` - Cubic spline interpolation
|
|
84
|
+
- `TOYMD.F`, `LEAP.F`, `JULDAT.F`, `MDAY.F` - Date/time utilities
|
|
85
|
+
- `ETUTC.F` - ET-UTC offset calculation
|
|
86
|
+
- `SHELLS.F` - Shell sort algorithm
|
|
87
|
+
|
|
88
|
+
## Key Functions Reference
|
|
89
|
+
|
|
90
|
+
### Date/Time Conversion Functions
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import hardisp
|
|
94
|
+
|
|
95
|
+
# Check if a year is a leap year
|
|
96
|
+
is_leap = pyhardisp.is_leap_year(2008) # Returns 1 for true, 0 for false
|
|
97
|
+
|
|
98
|
+
# Get days before start of month
|
|
99
|
+
days_before_may = pyhardisp.days_before_month(2009, 5) # Returns 120
|
|
100
|
+
|
|
101
|
+
# Convert to Julian Day Number
|
|
102
|
+
jd = pyhardisp.julian_date(2000, 1, 1) # Returns 2451545 (J2000.0)
|
|
103
|
+
|
|
104
|
+
# Convert day-of-year to month/day
|
|
105
|
+
y, m, d = pyhardisp.doy_to_ymd(2008, 120) # Returns (2008, 4, 29)
|
|
106
|
+
|
|
107
|
+
# Get ET-UTC offset for decimal year
|
|
108
|
+
delta = pyhardisp.earth_time_offset_seconds(2009.5) # Returns difference in seconds
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Tidal Calculations
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# Set the epoch for tidal calculations
|
|
115
|
+
pyhardisp.calculate_tidal_arguments(year=2009, day_of_year=176, hour=0, minute=0, second=0)
|
|
116
|
+
|
|
117
|
+
# Get frequency and phase of a tidal constituent
|
|
118
|
+
import numpy as np
|
|
119
|
+
doodson = np.array([2, 0, 0, 0, 0, 0]) # M2 tide
|
|
120
|
+
freq, phase = pyhardisp.tidal_frequency_and_phase(doodson)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Main Class: HardispComputer
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# Create a computer instance
|
|
127
|
+
computer = hardisp.HardispComputer()
|
|
128
|
+
|
|
129
|
+
# Load BLQ-format ocean loading coefficients
|
|
130
|
+
# Two methods:
|
|
131
|
+
|
|
132
|
+
# Method 1: From numpy arrays (3x11 each)
|
|
133
|
+
amp_data = [[0.00352, 0.00123, ...], [0.00144, ...], [0.00086, ...]]
|
|
134
|
+
phase_data = [[-64.7, -52.0, ...], [85.5, ...], [109.5, ...]]
|
|
135
|
+
computer.read_blq_format(amp_data, phase_data)
|
|
136
|
+
|
|
137
|
+
# Method 2: From BLQ text file (6 lines)
|
|
138
|
+
with open('station.blq', 'r') as f:
|
|
139
|
+
lines = f.readlines()
|
|
140
|
+
computer.read_blq_format(lines[:3], lines[3:])
|
|
141
|
+
|
|
142
|
+
# Compute ocean loading effects
|
|
143
|
+
dz, ds, dw = computer.compute_ocean_loading(
|
|
144
|
+
year=2009, month=6, day=25,
|
|
145
|
+
hour=1, minute=10, second=45,
|
|
146
|
+
num_epochs=24, # Number of time points
|
|
147
|
+
sample_interval=3600.0 # Seconds between points
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Output units depend on input coefficients from the ocean loading provider
|
|
151
|
+
# Pass units as metadata to document what you expect (doesn't affect computation)
|
|
152
|
+
print(f"Vertical: {dz}")
|
|
153
|
+
print(f"South: {ds}")
|
|
154
|
+
print(f"West: {dw}")
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Usage Examples
|
|
158
|
+
|
|
159
|
+
### Example 1: Simple Time Series
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
import pyhardisp
|
|
163
|
+
import numpy as np
|
|
164
|
+
|
|
165
|
+
# Create computer instance
|
|
166
|
+
computer = pyhardisp.HardispComputer()
|
|
167
|
+
|
|
168
|
+
# Load BLQ ocean loading coefficients
|
|
169
|
+
amplitudes = [
|
|
170
|
+
[45.96, 10.98, 6.94, 3.07, 6.00, 1.57, 1.98, 0.91, 1.58, 0.73, 0.41], # Vertical
|
|
171
|
+
[99.00, 14.68, 21.49, 4.16, 2.67, 2.80, 0.86, 1.03, 0.02, 0.00, 0.01], # East
|
|
172
|
+
[38.30, 11.46, 8.92, 3.17, 7.47, 4.96, 2.46, 0.97, 1.06, 0.63, 0.52], # North
|
|
173
|
+
]
|
|
174
|
+
phases = [
|
|
175
|
+
[53.3, 137.3, 22.4, 135.1, -171.3, 21.5, -170.7, 42.9, -3.6, -8.3, -4.3],
|
|
176
|
+
[140.1, 174.5, 123.5, 159.1, 167.5, 93.9, 168.8, 65.9, -47.8, -49.7, 15.5],
|
|
177
|
+
[-109.9, -78.7, -133.4, -85.9, 28.6, 12.2, 28.1, 16.0, 14.1, 8.0, 1.5],
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
computer.read_blq_format(amplitudes, phases, units="nm/s^2")
|
|
181
|
+
|
|
182
|
+
# Compute 24 hourly displacements
|
|
183
|
+
dz, ds, dw = computer.compute_ocean_loading(
|
|
184
|
+
year=2009, month=6, day=25,
|
|
185
|
+
hour=1, minute=10, second=45,
|
|
186
|
+
num_epochs=24,
|
|
187
|
+
sample_interval=3600.0
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
print("Vertical gravity (nm/s^2):", dz)
|
|
191
|
+
print("South tilt (nrad): ", ds)
|
|
192
|
+
print("West tilt (nrad): ", dw)
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Example 2: High-Rate Analysis
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
# For 1Hz sampling (e.g., seismic or structural monitoring)
|
|
199
|
+
dz_high, ds_high, dw_high = computer.compute_ocean_loading(
|
|
200
|
+
year=2009, month=6, day=25,
|
|
201
|
+
hour=1, minute=0, second=0,
|
|
202
|
+
num_epochs=86400, # Full day at 1Hz
|
|
203
|
+
sample_interval=1.0 # 1 second intervals
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Example 3: Multi-Day Campaign
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# Process multiple days
|
|
211
|
+
for day_val in range(1, 8): # Process days 1-7
|
|
212
|
+
dz, ds, dw = computer.compute_ocean_loading(
|
|
213
|
+
year=2009, month=6, day=day_val,
|
|
214
|
+
num_epochs=1, sample_interval=1
|
|
215
|
+
)
|
|
216
|
+
print(f"June {day_val}: max effect = {max(abs(dz), abs(ds), abs(dw)):.6f}")
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Technical Details
|
|
220
|
+
|
|
221
|
+
### Coordinate System
|
|
222
|
+
|
|
223
|
+
The output displacements are in a **local geodetic frame** at the station:
|
|
224
|
+
- **dU**: Radial (positive upward)
|
|
225
|
+
- **dS**: South component (positive southward, i.e., negative latitude direction)
|
|
226
|
+
- **dW**: West component (positive westward, i.e., negative longitude direction)
|
|
227
|
+
|
|
228
|
+
### Tidal Constituents Used
|
|
229
|
+
|
|
230
|
+
The 11 input harmonics (from BLQ format) represent:
|
|
231
|
+
1. M₂ - Principal lunar semi-diurnal (12.42 hours)
|
|
232
|
+
2. S₂ - Principal solar semi-diurnal (12.00 hours)
|
|
233
|
+
3. N₂ - Lunar elliptic semi-diurnal (12.66 hours)
|
|
234
|
+
4. K₂ - Lunisolar semi-diurnal (11.97 hours)
|
|
235
|
+
5. K₁ - Lunisolar diurnal (23.93 hours)
|
|
236
|
+
6. O₁ - Principal lunar diurnal (25.82 hours)
|
|
237
|
+
7. P₁ - Principal solar diurnal (24.07 hours)
|
|
238
|
+
8. Q₁ - Larger lunar elliptic diurnal (26.87 hours)
|
|
239
|
+
9. Mf - Lunar fortnightly (13.66 days)
|
|
240
|
+
10. Mm - Lunar monthly (27.55 days)
|
|
241
|
+
11. Ssa - Solar semi-annual (182.6 days)
|
|
242
|
+
|
|
243
|
+
These are expanded to 342 constituents through spline interpolation for higher precision.
|
|
244
|
+
|
|
245
|
+
### Recursion Algorithm
|
|
246
|
+
|
|
247
|
+
The program uses **Chebyshev polynomial recursion** for efficient computation of harmonic series:
|
|
248
|
+
|
|
249
|
+
Instead of computing: `x(t) = Σ A cos(ωt) + B sin(ωt)`
|
|
250
|
+
|
|
251
|
+
It uses: `x(j) = 2cos(ω)·x(j-1) - x(j-2)`
|
|
252
|
+
|
|
253
|
+
This requires only 2-3 operations per harmonic per time point, making it orders of magnitude faster than direct calculations, especially for large numbers of epochs.
|
|
254
|
+
|
|
255
|
+
## Conversion Notes
|
|
256
|
+
|
|
257
|
+
### Key Differences from Fortran
|
|
258
|
+
|
|
259
|
+
1. **Integer Division**: Fortran's division truncates toward zero, while Python's `//` uses floor division. The code uses `fortran_int_divide()` function to maintain Fortran semantics.
|
|
260
|
+
|
|
261
|
+
2. **Matrix Indexing**: Fortran uses 1-based indexing; Python uses 0-based. Conversions are handled automatically.
|
|
262
|
+
|
|
263
|
+
3. **Floating Point**: Results may differ slightly due to different floating-point implementations and optimization levels.
|
|
264
|
+
|
|
265
|
+
4. **Object-Oriented**: The Python version uses a class-based interface (`HardispComputer`) rather than standalone FORTRAN procedures.
|
|
266
|
+
|
|
267
|
+
## Original Fortran Files (Reference)
|
|
268
|
+
|
|
269
|
+
The Python code was converted from these 13 Fortran files:
|
|
270
|
+
|
|
271
|
+
1. `HARDISP.F` (465 lines) - Main program
|
|
272
|
+
2. `ADMINT.F` (449 lines) - Ocean loading interpolation
|
|
273
|
+
3. `RECURS.F` (180 lines) - Recursive harmonic evaluation
|
|
274
|
+
4. `TDFRPH.F` (281 lines) - Frequency and phase calculation
|
|
275
|
+
5. `SPLINE.F` (215 lines) - Spline setup
|
|
276
|
+
6. `EVAL.F` (197 lines) - Spline evaluation
|
|
277
|
+
7. `TOYMD.F` (160 lines) - Date conversion
|
|
278
|
+
8. `MDAY.F` (155 lines) - Month/day calculation
|
|
279
|
+
9. `LEAP.F` (154 lines) - Leap year check
|
|
280
|
+
10. `JULDAT.F` (159 lines) - Julian date
|
|
281
|
+
11. `SHELLS.F` (210 lines) - Shell sort
|
|
282
|
+
12. `ETUTC.F` (284 lines) - ET-UTC calculation
|
|
283
|
+
13. `TOYS.F` - (not in workspace but referenced)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
## Function Name Mapping (Original Fortran → New Python)
|
|
287
|
+
|
|
288
|
+
| Original Fortran | New Python Name | Purpose |
|
|
289
|
+
|------------------|-----------------|----------|
|
|
290
|
+
| LEAP | is_leap_year | Check leap year status |
|
|
291
|
+
| MDAY | days_before_month | Days before month start |
|
|
292
|
+
| JULDAT | julian_date | Convert to Julian Day Number |
|
|
293
|
+
| TOYMD | doy_to_ymd | Convert day-of-year to month/day |
|
|
294
|
+
| ETUTC | earth_time_offset_seconds | ET-UTC offset calculation |
|
|
295
|
+
| SPLINE | cublic_spline | Compute cubic spline coefficients |
|
|
296
|
+
| EVAL | spline_eval | Evaluate spline at point |
|
|
297
|
+
| — | spline_eval_batch | Evaluate spline at multiple points (vectorized) |
|
|
298
|
+
| SET_TIDAL_DATE | calculate_tidal_arguments | Initialize tidal calculations |
|
|
299
|
+
| TDFRPH | tidal_frequency_and_phase | Get frequency and phase |
|
|
300
|
+
| — | tidal_frequency_and_phase_batch | Get frequencies/phases for multiple constituents (vectorized) |
|
|
301
|
+
| RECURS | recursion | Recursive harmonic evaluation |
|
|
302
|
+
| ADMINT | admittance | Admittance interpolation |
|
|
303
|
+
| SHELLS | pyshells | Shell sort array indices |
|
|
304
|
+
| int_div (helper) | fortran_int_divide | Fortran-style integer division |
|
|
305
|
+
|
|
306
|
+
## Features Implemented
|
|
307
|
+
|
|
308
|
+
### Complete Conversion
|
|
309
|
+
- [x] All 342 tidal constituents support
|
|
310
|
+
- [x] Recursive harmonic evaluation (efficient)
|
|
311
|
+
- [x] Cubic spline interpolation
|
|
312
|
+
- [x] Tidal admittance calculation
|
|
313
|
+
- [x] BLQ format input/output
|
|
314
|
+
- [x] Julian date calculations
|
|
315
|
+
- [x] ET-UTC offset (with leap seconds through 2017)
|
|
316
|
+
- [x] Doodson number computations
|
|
317
|
+
- [x] Delaunay argument calculations
|
|
318
|
+
|
|
319
|
+
### Additional Features
|
|
320
|
+
- [x] Object-oriented design with HardispComputer class
|
|
321
|
+
- [x] NumPy integration for high performance
|
|
322
|
+
- [x] Comprehensive error handling
|
|
323
|
+
- [x] Detailed documentation and docstrings
|
|
324
|
+
- [x] Test cases and validation
|
|
325
|
+
- [x] Performance optimizations
|
|
326
|
+
|
|
327
|
+
## Core Components Converted
|
|
328
|
+
|
|
329
|
+
### 1. Date/Time Functions (7 functions)
|
|
330
|
+
```
|
|
331
|
+
✓ is_leap_year(year) - Check leap year
|
|
332
|
+
✓ days_before_month(year, month) - Days before month start
|
|
333
|
+
✓ julian_date(year, month, day) - Convert to Julian date
|
|
334
|
+
✓ doy_to_ymd(year, day_of_year) - Convert to month/day
|
|
335
|
+
✓ earth_time_offset_seconds(year) - ET-UTC offset calculation
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### 2. Spline Interpolation (3 functions)
|
|
339
|
+
```
|
|
340
|
+
✓ cublic_spline(x, u) - Compute cubic spline coefficients
|
|
341
|
+
✓ spline_eval(y, x, u, s) - Evaluate spline at point
|
|
342
|
+
✓ spline_eval_batch(y_arr, x, u, s) - Evaluate spline at multiple points (vectorized)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 3. Tidal Frequency Calculations (3 functions)
|
|
346
|
+
```
|
|
347
|
+
✓ calculate_tidal_arguments(year, day, h, m, s) - Initialize tidal calculations
|
|
348
|
+
✓ tidal_frequency_and_phase(doodson_number) - Get frequency and phase from Doodson number
|
|
349
|
+
✓ tidal_frequency_and_phase_batch(doodson_array) - Get frequencies and phases for multiple constituents (vectorized)
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### 4. Harmonic Recursion (1 function)
|
|
353
|
+
```
|
|
354
|
+
✓ recursion(n, hc, nf, om) - Efficient recursive harmonic evaluation
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### 5. Utility Functions (2 functions)
|
|
358
|
+
```
|
|
359
|
+
✓ pyshells(x) - Sort array with indices (Shell sort)
|
|
360
|
+
✓ fortran_int_divide(a, b) - Fortran-style integer division
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### 6. Main Class: HardispComputer
|
|
364
|
+
```
|
|
365
|
+
✓ read_blq_format(amp, phase) - Load ocean loading coefficients
|
|
366
|
+
✓ compute_ocean_loading(...) - Main computation engine
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
## References
|
|
372
|
+
|
|
373
|
+
1. Petit, G. and Luzum, B. (eds.), **IERS Conventions (2010)**, IERS Technical Note No. 36, BKG (2010)
|
|
374
|
+
- Available at: https://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.php
|
|
375
|
+
|
|
376
|
+
2. Agnew, D. C., et al., **HARDISP**: Original algorithm and implementation
|
|
377
|
+
|
|
378
|
+
3. Scherneck, H.-G., and M. S. Bos, **Ocean Loading Service**: BLQ format specification
|
|
379
|
+
- Available at: http://www.oso.chalmers.se/~loading/
|
|
380
|
+
|
|
381
|
+
4. Cartwright, D. E., and A. C. Edden, **Tides of the Planet Earth**, Geophys. J. R. Astron. Soc. 65, 615-630, 1981
|
|
382
|
+
|
|
383
|
+
## License
|
|
384
|
+
|
|
385
|
+
This Python conversion maintains the same IERS Conventions Software License as the original Fortran code. See copyright notices in source files.
|
|
386
|
+
|
|
387
|
+
## Contact
|
|
388
|
+
|
|
389
|
+
For questions or issues with the Fortran original:
|
|
390
|
+
- IERS Conventions Center: https://www.iers.org/
|
|
391
|
+
- Email: gpetit@bipm.org or brian.luzum@usno.navy.mil
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
*Python conversion completed: 2024*
|
|
396
|
+
*Original Fortran: IERS Conventions 2010*
|