Getting Started#

Installation#

PyFES is distributed as pre-built binaries on both PyPI and conda-forge, so most users do not need a C++ toolchain to install it.

From PyPI (pip)#

Binary wheels are published on PyPI for:

  • Linuxmanylinux_2_28 on x86_64 and aarch64 (glibc ≥ 2.28)

  • macOSarm64 (Apple Silicon), deployment target 13.4

  • Windowsx86_64

Wheels are built for CPython 3.11, 3.12, 3.13, 3.14 and the free-threaded build 3.14t.

pip install pyfes

To upgrade to the latest release:

pip install -U pyfes

Pre-release builds (X.Y.ZrcN, X.Y.Z.devN) are uploaded to TestPyPI:

pip install --index-url https://test.pypi.org/simple/ \
    --extra-index-url https://pypi.org/simple/ pyfes

If no wheel matches your platform or interpreter, pip falls back to building from source — see Building from Source below for the prerequisites.

From conda-forge#

conda install -c conda-forge pyfes

Building from Source#

PyFES requires a C++14 compiler, CMake, Boost (≥ 1.79) and Eigen (≥ 3.4) to build from source:

git clone https://github.com/CNES/aviso-fes.git
cd aviso-fes
pip install -e .

Build options#

The build_ext command exposes several options to customise the build. Pass them through setup.py directly, or via pip install using the --config-settings flag (one --config-settings=--build-option=<flag> per flag, since pip forwards each value as a single token).

Option

Description

--cxx-compiler=<path>

Path to the preferred C++ compiler. Translated to -DCMAKE_CXX_COMPILER=....

--generator=<name>

CMake generator to use (e.g. Ninja, "Unix Makefiles").

--cmake-args="<args>"

Extra arguments forwarded verbatim to CMake (space-separated, quote the whole value).

--mkl[=yes|no]

Use Intel MKL as the BLAS implementation. When the MKL header is available under $CONDA_PREFIX, MKLROOT is set automatically.

--iers[=yes|no]

Compile with the IERS 2010 astronomic constants instead of the Schureman (1958) values. Defines -DFES_USE_IERS_CONSTANTS=ON. See Astronomic Constants for the difference.

--reconfigure

Force CMake to re-run from scratch (drops the cached configuration).

In addition, when CONDA_PREFIX is set, -DCMAKE_PREFIX_PATH=$CONDA_PREFIX is added automatically so dependencies installed in the active conda environment are picked up.

Examples#

Editable install with Ninja and the IERS 2010 constants:

python setup.py build_ext --generator=Ninja --iers --inplace
pip install -e . --no-build-isolation

Same thing through pip:

pip install -e . --no-build-isolation \
    --config-settings=--build-option=build_ext \
    --config-settings=--build-option=--generator=Ninja \
    --config-settings=--build-option=--iers

Forwarding raw CMake options (here, an explicit Boost root):

python setup.py build_ext \
    --cmake-args="-DBOOST_ROOT=/opt/boost -DCMAKE_BUILD_TYPE=Release"

Quickstart: Predicting Tides from a Model#

The most common use case is predicting ocean tides at given locations and times using a tidal atlas (FES2022, GOT5.6, etc.).

Step 1: Create a YAML Configuration File#

The configuration file describes your tidal model and selects the prediction engine. Here is a minimal example for a FES atlas with Cartesian grids:

engine: darwin
tide:
  cartesian:
    paths:
      M2: /path/to/M2_tide.nc
      S2: /path/to/S2_tide.nc
      K1: /path/to/K1_tide.nc
      O1: /path/to/O1_tide.nc
      # ... additional constituents

The top-level engine key selects the prediction engine: darwin for FES atlases or perth for GOT atlases. See Prediction Engines for details on each engine.

Environment variables are supported using ${VAR} syntax:

engine: darwin
tide:
  cartesian:
    paths:
      M2: ${FES_DATA}/M2_tide.nc

Step 2: Load the Model and Predict#

import numpy as np
import pyfes

# Load the tidal model and settings from the YAML file
config = pyfes.config.load('ocean_tide.yaml')

# Define the prediction coordinates and times
dates = np.arange(
    np.datetime64('2024-01-01'),
    np.datetime64('2024-01-02'),
    np.timedelta64(1, 'h'),
)
lons = np.full(dates.shape, -7.688)   # longitude in degrees
lats = np.full(dates.shape, 59.195)   # latitude in degrees

# Compute the tide
tide, lp, flags = pyfes.evaluate_tide(
    config.models['tide'], dates, lons, lats,
    settings=config.settings,
)

# tide: short-period constituent heights (cm)
# lp: long-period equilibrium tide (cm)
# flags: quality flags (>0: interpolated, <0: extrapolated, 0: undefined)
total_tide = tide + lp

The load() function returns a Configuration named tuple containing:

  • models: a dictionary mapping 'tide' (and optionally 'radial') to tidal model objects.

  • settings: the runtime settings appropriate for the chosen engine (FESSettings or PerthSettings).

The actual prediction is performed by evaluate_tide(), which evaluates the configured model at the requested times and locations.

Quickstart: Prediction from Known Constituents#

If you already know the tidal constituents at a location (e.g., from harmonic analysis of tide gauge data), you can predict tides directly:

import numpy as np
import pyfes

# Constituents from harmonic analysis: {name: (amplitude_cm, phase_deg)}
constituents = {
    'M2': (205.1, 109.0),
    'S2': (74.9, 148.3),
    'K1': (6.4, 75.1),
    'O1': (6.6, 327.9),
}

dates = np.arange(
    np.datetime64('2024-01-01'),
    np.datetime64('2024-01-02'),
    np.timedelta64(1, 'h'),
)

tide, lp = pyfes.evaluate_tide_from_constituents(
    constituents, dates, latitude=48.38,
)

See evaluate_tide_from_constituents() for the full API.

Limiting the Loaded Region#

For large global atlases, you can load only a regional subset using the bbox parameter:

config = pyfes.config.load(
    'ocean_tide.yaml',
    bbox=(-10, 40, 10, 60),  # (min_lon, min_lat, max_lon, max_lat)
)

Next Steps#