Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/test_conda_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ channels:
dependencies:
- numpy
- pandas
- fortran-compiler
19 changes: 16 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,33 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest, macos-latest, windows-latest]
python: ["3.10", "3.14"]
exclude:
- os: windows-latest
python: "3.10"
include:
- python: "3.10"
- os: windows-latest
python: "3.12"
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
steps:
- uses: actions/checkout@v3
- uses: fortran-lang/setup-fortran@v1
id: setup-fortran
with:
compiler: gcc
- name: setup conda
uses: conda-incubator/setup-miniconda@v2
uses: conda-incubator/setup-miniconda@v3
with:
python-version: ${{ matrix.python }}
auto-update-conda: true
environment-file: .github/test_conda_env.yml
- name: install gfortran runtime (Windows)
if: runner.os == 'Windows'
run: conda install -y -c conda-forge gfortran
- name: print conda environment info
run: |
conda info -a
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
v0.8.0:
* modernisation of update script and test script and build system by Craig Miller, ESNZ.
v0.7.1:
* record length was corrected
* length of day (LOD) tide is now properly interpolated
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
include README.md
include pygtide/etpred.*

92 changes: 58 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,49 +14,73 @@ There are two options:

## How to install and run

Instructions:
### Prerequisites

* Download and install [*Anaconda*](https://www.anaconda.com/products/distribution) or [*Miniconda*](https://docs.conda.io/en/latest/miniconda.html)
* Install required packages:
```
conda install numpy pandas requests
```

### Installation options

* Make sure the following packages are installed: <br />
`conda install numpy pandas requests git`

* Download and install pygtide:
* *Linux* or *MacOS*: <br />
**NOTE**: Make sure suitable C++ and Fortran compilers are available.
```
pip install pygtide
```

* *Windows*:<br />
Download the correct wheel for your Python version (available for 3.8 to 3.11) from the subfolder "windows" onto your system.
Then navigate your Anaconda explorer to the download location and execute:
```
pip install [wheel_name_depending_on_python_version]
```

* Run tests: <br />
```
python -c "import pygtide; pygtide.test(msg=True)"
```
* The internal database files can be updated as follows: <br />
```
python -c "import pygtide; pygtide.update()"
```
* See `pygtide/tests.py` for example usage:
#### Option 1: Install and compile source distribution from PyPi (Linux, macOS, Windows; Python 3.8–3.14)

```bash
pip install pygtide
```
from pygtide import predict_series
args = (-20.82071, -70.15288, 830.0, '2020-01-01', 6, 600)
series = predict_series(*args, statazimut=90, tidalcompo=8)

#### Option 2: Build from source locally (Linux, macOS, Windows; Python 3.8–3.14)

**Requirements for building:**
- A Fortran compiler (e.g., `gfortran` via MinGW on Windows; included in Linux/macOS gcc toolchains) `conda install gfortran`
- Meson build system with ninja: automatically installed via `pip`

**Clone repo from git:**
```bash
git clone https://github.com/hydrogeoscience/pygtide.git
```

**Install from local repository:**
```bash
cd /path/to/pygtide

pip install .
```

If Meson or Ninja are missing, pip will attempt to install them automatically. For faster builds, pre-install them:
```bash
pip install meson-python meson ninja
```

#### Option 3: Pre-built wheels (Windows, Python 3.8–3.11)
Download the correct wheel for your Python version from the `windows/` subfolder and install:
```powershell
pip install [wheel_name_depending_on_python_version]
```

* Development version: This can be installed by downloading the Github repository and running:
`pip install download_path`. <br />
Alternatively, in one step as: <br />
### After installation

* Run tests to verify installation:
```
python -c "import pygtide; pygtide.test(msg=True)"
```

* Update internal database files (downloads latest leap seconds and pole data):
```
pip install git+https://github.com/hydrogeoscience/pygtide.git
python -c "import pygtide; pygtide.update()"
```

### Example usage

See `pygtide/tests.py` for complete examples. Quick start:

```python
from pygtide import predict_series
args = (-20.82071, -70.15288, 830.0, '2020-01-01', 6, 600)
series = predict_series(*args, statazimut=90, tidalcompo=8)
```

## How to use

An updated user guide is currently in progress ...
Expand Down
47 changes: 47 additions & 0 deletions build_pygtide_abi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import subprocess
import shutil
import os
import glob
import sys


def build():
# --- Configuration ---
print('Start Meson build')
build_dir = 'build_abi'
ext = 'pyd' if os.name == 'nt' else 'so'

# --- Step 1: Setup Meson build directory ---
if os.path.exists(build_dir):
print(f"Build directory '{build_dir}' already exists, skipping setup.")
else:
print(f"Setting up Meson build directory '{build_dir}'...")
subprocess.check_call(['meson', 'setup', build_dir])
# --- Step 2: Compile Meson targets ---
print("Compiling Meson targets...")
subprocess.check_call(['meson', 'compile', '-C', build_dir])

# --- Step 3: Copy ABI module to pygtide/ ---
print("Locating ABI module in build directory...")
build_path = os.path.abspath(build_dir)
pattern = os.path.join(build_path, '**', f'etpred*.{ext}')
matches = glob.glob(pattern, recursive=True)

if not matches:
print("ERROR: ABI module not found! Did Meson compile succeed?")
sys.exit(1)

dst = os.path.join(os.path.abspath('.'), 'pygtide', f'etpred.{ext}')
shutil.copy(matches[0], dst)
print(f"Copied ABI module {matches[0]} -> {dst}")

# --- Step 4: Clean up build directory ---
print(f"Deleting build directory '{build_dir}'...")
shutil.rmtree(build_dir)
print("Meson build complete!")

#print("\nNext step: run 'pip install .' or 'pip install -e .' to install the package.")


if __name__ == '__main__':
build()
74 changes: 74 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
project('pygtide', 'fortran',
version : '0.8.0',
meson_version : '>=1.1.0',
)

py = import('python').find_installation()

host_os = host_machine.system()
fc = meson.get_compiler('fortran')

if host_os == 'windows'
ext = 'pyd'
if fc.get_id() == 'msvc'
f90flags = ['/O2']
else
f90flags = ['-O3']
endif
else
ext = 'so'
f90flags = ['-fPIC', '-O3']
endif

src = 'src/etpred.f90'
f90_flag_args = ['--f90flags=' + ' '.join(f90flags)]

# --------------------------------------------------
# 1. Build f2py (ABI-tagged output)
# --------------------------------------------------
etpred_build = custom_target(
'etpred_build',
input : src,
output : 'etpred.build.stamp',
command : [
py,
'-m', 'numpy.f2py',
'-c',
] + f90_flag_args + [
'-m', 'etpred',
'@INPUT@',
],
build_by_default : true,
)

# --------------------------------------------------
# 2. Copy ABI module → pygtide/etpred.pyd
# --------------------------------------------------
copy_code = '''
import glob, os, shutil, sys

build_dir = os.getcwd()
src_root = r"@0@"

pattern = os.path.join(build_dir, '**', 'etpred*.@1@')
matches = glob.glob(pattern, recursive=True)

if not matches:
print("ERROR: etpred ABI module not found")
sys.exit(1)

dst = os.path.join(src_root, 'pygtide', 'etpred.@1@')
shutil.copy(matches[0], dst)
print(f"Copied {matches[0]} -> {dst}")
'''.format(
meson.project_source_root(),
ext
)

custom_target(
'copy_etpred',
input : etpred_build,
output : 'etpred.copy.stamp',
command : [py, '-c', copy_code],
build_by_default : true,
)
21 changes: 19 additions & 2 deletions pygtide/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,22 @@
from pygtide.core import predict_series, predict_spectrum, predict_table
from pygtide.core import plot_series, plot_spectrum
from pygtide.tests import test
# from pygtide.update_etpred_data import update
__version__ = '0.8'
from pygtide.update_etpred_data import update

from importlib.metadata import version

try:
__version__ = version("pygtide")
except Exception:
__version__ = "0.8.0"

__all__ = [
"pygtide",
"predict_series",
"predict_spectrum",
"predict_table",
"plot_series",
"plot_spectrum",
"test",
"update",
]
Loading