{"id":46441077,"url":"https://github.com/craigmillernz/pyhardisp","last_synced_at":"2026-05-24T22:04:54.362Z","repository":{"id":341484921,"uuid":"1170161431","full_name":"craigmillernz/pyhardisp","owner":"craigmillernz","description":"Pyhardisp is a python implementation of the IERS Hardisp code for ocean loading","archived":false,"fork":false,"pushed_at":"2026-05-14T22:14:29.000Z","size":576,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-14T23:27:08.106Z","etag":null,"topics":["geodesy","geophysics","gravity"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/pyhardisp/","language":"Fortran","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/craigmillernz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_IERS.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-01T19:40:12.000Z","updated_at":"2026-05-14T21:31:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/craigmillernz/pyhardisp","commit_stats":null,"previous_names":["craigmillernz/pyhardisp"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/craigmillernz/pyhardisp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigmillernz%2Fpyhardisp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigmillernz%2Fpyhardisp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigmillernz%2Fpyhardisp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigmillernz%2Fpyhardisp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/craigmillernz","download_url":"https://codeload.github.com/craigmillernz/pyhardisp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/craigmillernz%2Fpyhardisp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33452050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-24T19:21:36.376Z","status":"ssl_error","status_checked_at":"2026-05-24T19:21:10.562Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["geodesy","geophysics","gravity"],"created_at":"2026-03-05T21:58:14.027Z","updated_at":"2026-05-24T22:04:54.338Z","avatar_url":"https://github.com/craigmillernz.png","language":"Fortran","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pyhardisp Python Module - Quick Start Guide\n\n[![codecov](https://codecov.io/gh/craigmillernz/pyhardisp/branch/main/graph/badge.svg)](https://codecov.io/gh/craigmillernz/pyhardisp)\n![Build and Publish](https://github.com/craigmillernz/pyhardisp/actions/workflows/build.yml/badge.svg)\n[![Pypi version](https://img.shields.io/pypi/v/pyhardisp)](https://pypi.org/project/pyhardisp/)\n[![conda-forge](https://img.shields.io/conda/vn/conda-forge/pyhardisp.svg)](https://anaconda.org/conda-forge/pyhardisp)\n[![License](https://img.shields.io/badge/license-custom-lightgrey.svg)](LICENCE)\n[![DOI](https://zenodo.org/badge/1170161431.svg)](https://doi.org/10.5281/zenodo.20189637)\n\n## 📋 What is HARDISP vs pyhardisp?\n\n**HARDISP** computes ocean loading tidal effects for geodetic stations. It processes coefficients provided by ocean loading providers ([such as the Bos-Scherneck service](https://barre.oso.chalmers.se/loading/l.php)) to compute either:\n\n- **Displacements** (vertical and horizontal) when displacement-type coefficients are provided\n- **Gravity effects** (gravity (nm/s^2) and tilt(nrads)) when gravity-type coefficients are provided\n\nIt's part of the IERS Conventions 2010 recommended models for correcting space geodesy observations (GPS, SLR, VLBI, superconducting gravimeters).\n\n**pyhardisp** is a python conversion of the original HARDISP fortran code from IERS (available in the src dir).\n\n## Installation \u0026 Requirements\n\n```bash\n# Requires:\n- Python 3.11+\n- NumPy (\u003e 1.19)\n\n# Installation:\n1. pip install pyhardisp\nor\n2. conda install -c conda-forge pyhardisp\n\n```\n\n## 📂 Files in This Directory\n\n### Python Module\n\n- **`core.py`**\n  - Complete Python implementation of HARDISP\n  - Vectorised routines for speed enhancement\n\n### Documentation\n\n- **`README_PYTHON_CONVERSION.md`** - Complete user guide with examples\n- **`README.md`** - This file\n\n### Original Fortran Code from IERS (Reference Only)\n\n- `HARDISP.F` - Main program\n- `ADMINT.F` - Admittance interpolation\n- `RECURS.F` - Recursive evaluation\n- `TDFRPH.F` - Frequency and phase\n- `SPLINE.F`, `EVAL.F` - Interpolation\n- `TOYMD.F`, `MDAY.F`, `LEAP.F`, `JULDAT.F` - Date utilities\n- `ETUTC.F` - ET-UTC offset\n- `SHELLS.F` - Sorting\n- `makefile.txt` - Original build configuration\n\n## 🚀 Quick Start (5 minutes)\n\n### 1. Import the Module\n\n```python\nimport pyhardisp\n```\n\n### 2. Create a Computer\n\n```python\ncomputer = pyhardisp.HardispComputer()\n```\n\n### 3. Load Your Data\n\n```python\n# Ocean loading coefficients (from BLQ format)\n# 3 rows (vertical, east, north) × 11 columns (tidal constituents)\namplitudes = [\n    [45.96, 10.98, 6.94, 3.07, 6.00, 1.57, 1.98, 0.91, 1.58, 0.73, 0.41],  # Vertical nm/s^2\n    [99.00, 14.68, 21.49, 4.16, 2.67, 2.80, 0.86, 1.03, 0.02, 0.00, 0.01],  # East nrad\n    [38.30, 11.46, 8.92, 3.17, 7.47, 4.96, 2.46, 0.97, 1.06, 0.63, 0.52],  # North nrad\n]\nphases = [\n    [53.3, 137.3, 22.4, 135.1, -171.3, 21.5, -170.7, 42.9, -3.6, -8.3, -4.3], # degrees\n    [140.1, 174.5, 123.5, 159.1, 167.5, 93.9, 168.8, 65.9, -47.8, -49.7, 15.5], # degrees\n    [-109.9, -78.7, -133.4, -85.9, 28.6, 12.2, 28.1, 16.0, 14.1, 8.0, 1.5], # degrees\n]\n\ncomputer.read_blq_format(amplitudes, phases, units=\"nm/s2\")\n```\n\n### 4. Compute Displacements\n\n```python\ndz, ds, dw = computer.compute_ocean_loading(\n    year=2018, month=4, day=5,\n    hour=0, minute=32, second=30,\n    num_epochs=1,        # 24 hours\n    sample_interval=10  # Hourly (3600 seconds)\n)\n```\n\n### 5. Use the Results\n\n```python\n# Results are in nm/s^2 for vertical or nrad for horizontal components\nfor i in range(24):\n    print(f\"Hour {i}: Gravity={dz[i]:.6f} nm/s^2, South_tilt={ds[i]:.6f} nrad, West_tilt={dw[i]:.6f} nrad\")\n```\n\n## Example Output\n\n```\nHour 0: Gravity=-46.218473 nm/s^2, South_tilt=31.320275 nrad, West_tilt=-62.009276 nrad\nHour 1: Gravity=-46.166374 nm/s^2, South_tilt=31.286324 nrad, West_tilt=-62.111623 nrad\nHour 2: Gravity=-46.114183 nm/s^2, South_tilt=31.252307 nrad, West_tilt=-62.213840 nrad\nHour 3: Gravity=-46.061900 nm/s^2, South_tilt=31.218223 nrad, West_tilt=-62.315927 nrad\nHour 4: Gravity=-46.009525 nm/s^2, South_tilt=31.184073 nrad, West_tilt=-62.417885 nrad\nHour 5: Gravity=-45.957058 nm/s^2, South_tilt=31.149856 nrad, West_tilt=-62.519712 nrad\nHour 6: Gravity=-45.904499 nm/s^2, South_tilt=31.115573 nrad, West_tilt=-62.621408 nrad\nHour 7: Gravity=-45.851848 nm/s^2, South_tilt=31.081224 nrad, West_tilt=-62.722974 nrad\nHour 8: Gravity=-45.799106 nm/s^2, South_tilt=31.046809 nrad, West_tilt=-62.824409 nrad\nHour 9: Gravity=-45.746273 nm/s^2, South_tilt=31.012328 nrad, West_tilt=-62.925713 nrad\n```\n\n## Key Functions Reference\n\n| Function | Purpose |\n|----------|---------|\n| `is_leap_year(year)` | Check if year is leap year (returns 0 or 1) |\n| `days_before_month(year, month)` | Get days before month start |\n| `julian_date(year, month, day)` | Convert to Julian Day Number |\n| `doy_to_ymd(year, doy)` | Convert day-of-year to month/day |\n| `earth_time_offset_seconds(decimal_year)` | Get ET-UTC offset for year |\n| `calculate_tidal_arguments(y, doy, h, m, s)` | Set epoch for tidal calculations |\n| `tidal_frequency_and_phase(doodson_number)` | Get frequency and phase of a constituent |\n| `tidal_frequency_and_phase_batch(doodson_array)` | Get frequencies/phases for multiple constituents (vectorized) |\n| `HardispComputer()` | Main class for computing displacements |\n\n## 📖 Complete Documentation\n\nFor detailed information, see:\n\n1. **`README_PYTHON_CONVERSION.md`** (60+ pages)\n   - Complete technical reference\n   - Usage examples\n   - Function documentation\n   - Algorithm explanations\n   - Validation results\n\n## Technical Highlights\n\n- **342 tidal constituents** for precision of ~0.1%\n- **Recursive harmonic evaluation** for fast computation\n- **Cubic spline interpolation** for smooth admittance\n- **Efficient recursion algorithm**: O(N·M) vs O(N·M·T)\n- **NumPy integration** for high performance\n- **Object-oriented design** for ease of use\n\n## ✅ Validation\n\nAll results match original Fortran code:\n\nComparion with Quicktide Pro (QTP) and hardisp_x64.exe\n\n![Conparison of ocean loading from Quicktide Pro, gtools (using hardisp_x64.exe) and pyhardisp](./ocean_loading_comparison.png)\n\n## Understanding the Input Data\n\nThe BLQ format contains 11 tidal constituents:\n\n1. M₂ - Principal lunar semi-diurnal (12.42 hrs)\n2. S₂ - Principal solar semi-diurnal (12.00 hrs)\n3. N₂ - Lunar elliptic semi-diurnal (12.66 hrs)\n4. K₂ - Lunisolar semi-diurnal (11.97 hrs)\n5. K₁ - Lunisolar diurnal (23.93 hrs)\n6. O₁ - Principal lunar diurnal (25.82 hrs)\n7. P₁ - Principal solar diurnal (24.07 hrs)\n8. Q₁ - Lunar elliptic diurnal (26.87 hrs)\n9. Mf - Lunar fortnightly (13.66 days)\n10. Mm - Lunar monthly (27.55 days)\n11. Ssa - Solar semi-annual (182.6 days)\n\nThese are expanded to 342 constituents by the program for higher precision.\n\n## Data Sources\n\nOcean loading coefficients can be obtained from:\n\n**Bos \u0026 Scherneck Loading Service**\n\n- URL: \u003chttp://https://barre.oso.chalmers.se/loading/l.php/\u003e\n- Format: BLQ (Binary Loading Queue)\n- Coverage: Global\n- Models: Various (CSR, FES, etc.)\n\n## References\n\n1. **IERS Conventions (2010)**\n   - Petit, G. and Luzum, B. (eds.)\n   - Technical Note No. 36\n\n2. **Original HARDISP**\n   - Agnew, D. C., et al.\n   - Part of IERS software collection\n\n3. **Tidal Theory**\n   - Cartwright \u0026 Edden (1981)\n   - Doodson numbers and Darwin notation\n\n## Related Tools\n\n- **SPOTL** - SPOTL ocean loading (original basis for HARDISP)\n- **IERS Conventions Software** - Complete IERS implementations\n\n## Common Questions\n\n**Q: What are BLQ files?**  \nA: Ocean loading coefficients in binary format from the Chalmers university loading service.\n\n**Q: What units are the outputs?**  \nA: Meters for displacement (with typical values of ±0.01 m = ±1 cm), or nm/s^2 and nrad for gravity.\n\n**Q: How precise is HARDISP?**  \nA: Approximately 0.1% accuracy using 342 constituents\n\n**Q: Can I use different tidal constituents?**  \nA: Yes, modify the IDT array in the HardispComputer class\n\n**Q: What about non-Gregorian calendars?**  \nA: The code assumes Gregorian calendar (since ~1582)\n\n## Support\n\n- **For the original Fortran**: Contact IERS (\u003cgpetit@bipm.org\u003e)\n- **For this Python version**: Make an [issue](https://github.com/craigmillernz/pyhardisp)\n- **For BLQ data**: Contact Hans-Georg Scherneck (\u003cscherneck@oso.chalmers.se\u003e)\n\n## License\n\nThis Python version maintains the same IERS Conventions Software License as the original Fortran code. See copyright notices in the source files.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigmillernz%2Fpyhardisp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcraigmillernz%2Fpyhardisp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcraigmillernz%2Fpyhardisp/lists"}