For decades, underwater acoustic propagation models have been implemented in highly optimized Fortran/C code. For many years, wrapping these models in MATLAB was the natural solution adopted by the scientific community. As Python has become a dominant language in scientific computing, a noticeable gap has emerged. Despite multiple efforts to wrap or re-implement these models, Python users still lack a unified, comprehensive, and up-to-date solution.
UACPY is an attempt to close that gap.
It was created for researchers, engineers, oceanographers, and acousticians
who need underwater acoustic modeling to be more open, consistent,
transparent, and reproducible. It builds on decades of pioneering work in
the field and aims to provide a shared foundation for comparing models,
validating results, running experiments, and developing new ideas.
This project began as an AI-assisted (Claude Code with Sonnet 4.5, Opus 4.6 and 4.7) initiative to reduce early development time, but starting with the first release, it will be maintained manually by its author—without autonomous AI-driven modifications.
Community feedback, verification, and contributions are warmly encouraged. The project’s success depends on collective effort; the codebase is far too large and complex for one person to maintain alone in their spare time. The goal is for this module to be truly community-driven.
UACPY is not production‑ready. Expect missing features, inconsistencies, and the need for validation.
The changes between v0.3.x and v0.4.x are big, some of the API changed too.. This was done in order to clean up, harmonized and simplify the usage and maintainability. You will have to fully reinstall to compile RAMGeo, update AT and fetch data if you want to. Moreover, it comes with its bag of new features, including:
- RAMGeo
- Last updated version of AT toolbox
- Environment data fetching layer (based on GPS and date)
- Basic map plot and overview
- Basic SONAR performances
- Constant-Q transform family
- Ice support
- API harmonization
Project development will now focus on stabilization, bug fixes, and human review. The development of new features and the automated use of LLMs will be scaled back, API changes will be limited but may still occur in beta. The code base is quite big, and covers a wide range of scientific fields. To review such a technical work, it needs some community usage and feedback.
A unified Python API over the classical underwater‑acoustic propagation
models — consistent Environment / Source / Receiver construction and
Result objects — plus first‑class toolkits for everything around them.
Propagation models
| Model | Kind |
|---|---|
| Bellhop | Ray / beam tracing |
| Kraken | Normal modes |
| Scooter | Finite elements for range independent env |
| SPARC | Experimental time-marched FFP for pulses in range independent env |
| RAM | Parabolic equation |
| OASES | OAST (TL) · OASN (covariance / MFP replicas) · OASR (reflection) · OASP (broadband TRF) |
| Bounce | Reflection coefficients |
Toolkits — first‑class modules, not just glue around the models:
- Real‑world environments (
uacpy.data) — build anEnvironmentfrom GPS coordinates and a date, fetching bathymetry, sound‑speed, seafloor and sea‑ice data from public ocean databases (GEBCO, GMRT multibeam, World Ocean Atlas, Copernicus, EMODnet, NCEI/GlobSed/CRUST1 seabed, NSIDC sea ice). - Signal processing (
uacpy.acoustic_signal) — waveforms, matched filtering, beamforming, time‑frequency transforms, channel simulation. - Sonar performance (
uacpy.sonar) — sonar equation, scattering, reverberation, detection & range. - Communications (
uacpy.comms) — digital modems (PSK/QAM/OFDM…), equalization, FEC, and the NATO JANUS standard. - Ambient noise (
uacpy.noise) — Wenz spectra (wind / shipping / rain / thermal). - Standards & metrics — sound speed, decidecade bands, ship source level, marine‑mammal weighting.
- Visualization — TL maps, rays, modes, fields, cross‑model comparisons.
Simplest example — from GPS to a modelled field, the code that produces the figure above:
import numpy as np, matplotlib.pyplot as plt
import uacpy
from uacpy import data
from uacpy.models import Bellhop, RunMode
# 1. Fetch a real range-dependent environment from GPS + date — GEBCO bathymetry,
# WOA23 sound speed and NCEI seabed — across the North Sea shelf down into the
# Norwegian Trench.
A, B = (61.0, 2.0), (58.0, 5.0) # (lat, lon): North Sea shelf → Norwegian Trench
env = data.fetch_environment(A, transect_to=B, date='2026-01-15', bottom_sources='auto')
grid = data.fetch_bathy_grid((56.5, 62.0), (-2.0, 9.0)) # (lats, lons, depth)
# 2. Model transmission loss with Bellhop at 800 Hz, out to the transect length.
src = uacpy.Source(depths=100, frequencies=800)
rcv = uacpy.Receiver(depths=np.linspace(1, env.depth, 150),
ranges=np.linspace(100, env.max_range, 350)) # env range extent
tl = Bellhop().run(env, src, rcv, run_mode=RunMode.COHERENT_TL)
# 3. One call → the figure above: map · transmission loss · environment.
# The left map is pluggable (map_fn=); the default is the bathymetry map.
uacpy.plot.plot_overview(env, grid, transect=(A, B), tl=tl, source=src, receiver=rcv,
map_title="North Sea — Norwegian Trench (GEBCO)",
tl_title="Transmission loss (Bellhop, 800 Hz)",
env_title="Range-dependent environment A→B",
map_kwargs=dict(contours=True, aspect=1))
plt.show()Linux is the primary supported platform. macOS works with Homebrew. Windows is supported via WSL2 (Windows Subsystem for Linux) — see the Windows section below for why and how.
What install.sh builds:
| Tool | Required for |
|---|---|
python3 |
Driving install.sh and importing uacpy (always) |
gfortran, make |
OALIB, mpiramS, ramsurf (rams0.5 elastic + ramsurf1.5 rough surface), ramgeo (ramgeo1.5 layered fluid), OASES (Fortran models — always) |
git |
Cloning uacpy + submodules (always) |
tar |
Submodule unpacking + OASES archive (always) |
cmake, g++/clang++ |
C++ Bellhop variant (--bellhop cxx) |
CUDA toolkit (nvcc) |
GPU Bellhop variant (--bellhop cuda) — required when --bellhop cuda is passed; the installer hard-errors if nvcc is absent (no silent downgrade to cxx) |
curl |
OASES archive download (--oases yes) |
install.sh verifies these are present and aborts with a clear
message if anything is missing — it does not install system packages
itself. Provision the toolchain once for your platform, then run the
build.
1. Install dependencies
# Debian / Ubuntu
sudo apt-get update
sudo apt-get install -y gfortran make git \
cmake g++ curl tar python3-venv python3-pip
# Fedora / RHEL
sudo dnf install -y gcc-gfortran make git \
cmake gcc-c++ curl tar python3-virtualenv python3-pip
# Arch / Manjaro
sudo pacman -S --needed gcc-fortran make git \
cmake gcc curl tar python python-pipFor GPU Bellhop, additionally install the CUDA toolkit from your distribution or NVIDIA's site.
2. Clone, create venv, install
git clone --recurse-submodules https://github.com/ErVuL/uacpy.git
cd uacpy
python3 -m venv uacpy_venv
source uacpy_venv/bin/activate
pip install -e .
./install.sh./install.sh runs interactively by default. Useful flags:
| Flag | Effect |
|---|---|
-y / --yes |
Non-interactive — auto-detect everything |
--bellhop fortran |
Skip the C++ build (Fortran Bellhop is always built) |
--bellhop cxx |
Also build C++ Bellhop (CPU) |
--bellhop cuda |
Also build CUDA Bellhop (GPU, requires nvcc) |
--oases yes / no |
Download + build OASES (or skip the prompt) |
--data LIST |
Download public datasets for the uacpy.data offline backend into ./data_cache (gitignored). LIST is a comma list (gebco, woa23, sediment, emodnet, coastline, globsed, crust1, diesing, seaice) or all. See ./install.sh --help for sizes/licences. |
--no-models / --data-only |
Skip all native model builds (no compilers needed) — pure-Python install; pair with --data for an offline data-only setup |
--force |
Skip incremental builds; do a full clean rebuild of every selected component |
1. Install dependencies
# Install Homebrew (skip if 'brew' is already on PATH). See https://brew.sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Xcode Command Line Tools (provides make, clang, git, tar)
xcode-select --install
# Build dependencies. The 'gcc' formula provides gfortran on macOS.
brew install gcc cmake curl pythonCUDA Bellhop is not available on macOS (no NVIDIA toolkit). The C++
Bellhop variant (--bellhop cxx) builds fine with Apple's clang.
2. Clone, create venv, install
git clone --recurse-submodules https://github.com/ErVuL/uacpy.git
cd uacpy
python3 -m venv uacpy_venv
source uacpy_venv/bin/activate
pip install -e .
./install.sh(See the Linux section above for install.sh flags — they're identical
on macOS.)
uacpy on Windows runs inside WSL2 (Windows Subsystem for Linux), following the Linux instructions above.
WSL2 needs CPU virtualization extensions. Some computer ship with this disabled by default, so first of all enable hardware virtualization in your BIOS/UEFI.
In an elevated PowerShell (Run as Administrator):
wsl --install -d UbuntuReboot when prompted. Open Ubuntu (Start menu → "Ubuntu") and follow the Linux / Debian recipe from above:
sudo apt-get update
sudo apt-get install -y gfortran make git \
cmake g++ curl tar python3-venv python3-pip
cd ~
git clone --recurse-submodules https://github.com/ErVuL/uacpy.git
cd uacpy
python3 -m venv uacpy_venv
source uacpy_venv/bin/activate
pip install -e .
./install.shTip: clone into the WSL filesystem (
~/uacpy), not into/mnt/c/.... Cross-filesystem I/O is 10–20× slower and the Acoustics-Toolbox build does a lot of small file writes.
cd uacpy
git pull
source uacpy_venv/bin/activate
pip install -e .
rm -rf uacpy/bin # Optional (Required for v0.3.x -> v0.4.x)
rm -rf data_cache # Optional
./install.sh # Optional (Required for v0.3.x -> v0.4.x) pip uninstall uacpy
rm -rf uacpyThe full API reference lives in a single file:
DOCUMENTATION.md — quick start, environment setup,
per-model signatures, visualization, signal processing, noise, units, and
troubleshooting.
Inside uacpy/uacpy/examples/ you will find 37 example scripts numbered
sequentially (example_01_*.py through example_37_*.py) — from a first TL
field to communications modems, a standards-based noise-impact assessment, and a
GPS-to-modelled-field real-world pipeline. See the
examples index for a description
of each one.
UACPY uses pytest with custom markers for categorizing tests.
pytest and pytest-xdist are no longer pulled in by the runtime
dependency set — install the test extra to get them, or the dev extra
for the additional formatting / linting / coverage tooling:
# For running the test suite
pip install -e ".[test]"
# For development (test deps + black, flake8, pytest-cov)
pip install -e ".[dev]"Note: With macOS you may need to use pip install -e .\[xxx\].
cd uacpy
pytest uacpy/tests/
Tests use custom markers to allow selective execution:
slow-- Long-running tests (broadband, large grids, slow examples)requires_binary-- Tests that need compiled native binaries (Fortran/C)requires_oases-- Tests that need compiled OASES binariesrequires_network-- Tests that hit a live external service (theuacpy.datafetchers); auto-skipped when offline
# Skip slow tests
pytest uacpy/tests/ -m "not slow"
# Run only tests that don't need compiled binaries
pytest uacpy/tests/ -m "not requires_binary"
# Skip OASES tests (if OASES is not installed)
pytest uacpy/tests/ -m "not requires_oases"
# Skip all internet-dependent tests (also auto-skipped offline)
pytest uacpy/tests/ -m "not requires_network"
Because the initial codebase was LLM‑bootstrapped, auditing comes before new features. Both lists are contributor checklists — open an issue or PR for anything you investigate. Full diffs of in‑tree native‑model changes live in MODIFICATIONS.md.
- 🧱 API audit
- 🔬 Native model re‑validation
- 🐍 Python‑side review
- 📊 Visualization review
- 🧪 Test suite audit
- 📦 Build, install, packaging
- 🔁 CI / CD
If you are evaluating UACPY for a project: do not trust any specific number it produces until the re‑validation items above have been verified for the model and regime you care about.
- Model features — coverage of every native model option, GPU acceleration for more models, full 3‑D propagation.
- GUI — scenario‑based simulations, interactive TL / mode / noise level / ..., dashboards.
UACPY would not exist without decades of prior work by the underwater acoustics community. Every propagation model shipped here was designed, implemented, and validated elsewhere --- UACPY only provides a unified Python interface around them. Which codebases are vendored vs modified is summarised in the licensing table; full diffs for modified sources live in MODIFICATIONS.md.
Michael B. Porter --- http://oalib.hlsresearch.com/AcousticsToolbox/
- Porter, The BELLHOP Manual and User's Guide, 2011
- Porter, The KRAKEN Normal Mode Program, 1992
C. S. Schmid, D. F. Schmidt, A. E. Hodgson --- https://github.com/A-New-BellHope/bellhopcuda
- BellhopCUDA: High-Performance Acoustical Ray Tracing on GPUs, 2020
Michael D. Collins (Naval Research Laboratory)
- Collins, "A split-step Padé solution for the parabolic equation method," JASA, 1993
Brian D. Dushaw --- https://zenodo.org/records/10818570
Vendored from the Quiet Oceans repackaging of David C. Calvo's NRL distribution --- https://github.com/quiet-oceans/ramsurf
- Collins, A split-step Padé solution for the parabolic equation method, JASA, 1993
- Collins, Higher-order parabolic approximations for accurate and stable elastic parabolic equations with application to interface wave propagation, JASA, 1991 (RAMS / elastic)
- Collins, Generalization of the split-step Padé solution (variable surface / ramsurf), JASA 97, 2767–2770, 1995
Range-dependent layered-fluid parabolic-equation model by Michael D. Collins
(Naval Research Laboratory). Public domain — a U.S. Government work; the
source carries no copyright or licence notice. uacpy vendors it from the
Acoustics Toolbox RAM/ bundle (Porter's AT, mirroring
http://oalib.hlsresearch.com/Modes/AcousticsToolbox/), which merely
redistributes Collins' original.
- Collins, A split-step Padé solution for the parabolic equation method, JASA 93, 1736–1742, 1993
- Collins, Users Guide for RAM versions 1.0 and 1.0p / RAMGeo, NRL, 1999
Henrik Schmidt (Massachusetts Institute of Technology) --- https://acoustics.mit.edu/faculty/henrik/oases.html
Mandar Chitre (Acoustic Research Lab, National University of Singapore) --- https://github.com/org-arl/arlpy
Utility functions adapted into uacpy/core/acoustics.py preserve Mandar
Chitre's 2016 copyright header and cite arlpy as the source.
UACPY aggregates code from multiple projects, each under its own license. Downstream users are responsible for respecting each license when redistributing or modifying UACPY or its outputs.
| Component | Location | How it ships | License |
|---|---|---|---|
| UACPY wrapper | this repository | source + Python package | GPL-3.0 |
| Acoustics Toolbox (Porter) | third_party/Acoustics-Toolbox/ |
vendored Fortran sources, modified | GPL-3.0 |
| bellhopcuda (Schmid et al.) | third_party/bellhopcuda/ |
git submodule pinned to upstream v1.5, unmodified |
GPL-3.0 |
| mpiramS (Dushaw) | third_party/mpiramS/ |
vendored Fortran sources, modified | Creative Commons Attribution 4.0 International |
| ramsurf (Calvo / Quiet Oceans) | third_party/ramsurf/ |
vendored Fortran sources, modified | BSD-3-Clause |
| ramgeo (Collins, NRL) | third_party/ramgeo/ |
vendored Fortran source, modified | Public domain (U.S. Government work, no explicit licence) |
| arlpy utilities (Chitre) | uacpy/core/ |
adapted (ported into UACPY sources, unmodified scientifically) | BSD-3-Clause |
| OASES (Schmidt, MIT) | third_party/oases/ (gitignored) |
optional download at install time, not redistributed | Academic license --- see Henrik Schmidt's terms |
UACPY's runtime dependencies are installed from PyPI (not bundled or redistributed by UACPY); all are permissive and GPL-3.0-compatible.
| Package | Used for | License |
|---|---|---|
| numpy | arrays / numerics (core) | BSD-3-Clause |
| scipy | interpolation, FFT, nearest-neighbour search | BSD-3-Clause |
| matplotlib | visualization | Matplotlib License (PSF-based, BSD-style) |
| netCDF4 | reading WOA23 / GEBCO / GlobSed grids | MIT |
| shapely | EMODnet seabed-substrate polygon lookups | BSD-3-Clause |
| pyproj | map projections (sea-ice / Diesing reprojection) | MIT |
| tifffile | NSIDC sea-ice / lithology raster reads | BSD-3-Clause |
| copernicusmarine | Copernicus operational sound speed | EUPL-1.2 (lists GPL-3.0 as compatible) |
Test/development tooling (pytest, pytest-xdist, pytest-cov, black,
flake8 — the [test] / [dev] extras) is MIT-licensed and not required at
runtime.
The uacpy.data layer builds an Environment (and, for
uacpy.plot.plot_bathymetry_map, a coastline map) from public databases.
These datasets are fetched on demand - not redistributed with UACPY.
Their licences (CC-BY, CC-BY-NC, public domain, …) impose: whoever fetches
the data is its licensee and is responsible for honouring the licence and
citing the source. UACPY exposes a base_url= on each fetcher so heavy
users can point at their own mirror.
| Source | Used for | License | Required attribution / citation |
|---|---|---|---|
| GEBCO grid (served via OpenTopoData, MIT) | bathymetry | Public domain (attribution requested) | "GEBCO Compilation Group, GEBCO Grid" (see GEBCO terms for the grid DOI). OpenTopoData public API is fair-use: ≤1000 req/day, ≤1 req/s --- self-host for heavy use |
GMRT Global Multi-Resolution Topography (bathymetry_sources='gmrt') |
bathymetry (multibeam, higher-res) | CC-BY 4.0 | Ryan, W.B.F., et al. (2009). Global Multi-Resolution Topography synthesis. Geochem. Geophys. Geosyst. 10, Q03014. doi:10.1029/2008GC002332 |
| World Ocean Atlas 2023 (NOAA NCEI) | sound speed (climatology), absorption | U.S. Government work --- public domain | Reagan, J.R., et al. (2024). World Ocean Atlas 2023. NOAA National Centers for Environmental Information |
| Copernicus Marine Service (free account required) | sound speed (operational) | Copernicus Marine License (free; commercial use allowed; free account required) | "Generated using E.U. Copernicus Marine Service Information; <product DOI>" |
Argo float profiles (ssp_sources='argo', via Ifremer ERDDAP) |
sound speed (real in-situ profiles) | Free and unrestricted (Argo data policy) | "These data were collected and made freely available by the International Argo Program (argo.ucsd.edu)"; Argo (2024), Argo GDAC, SEANOE, doi:10.17882/42182 |
EMODnet Geology --- seabed substrate (bottom_sources='emodnet') |
sediment (European seas) | CC-BY 4.0 | "EMODnet Geology seabed substrate (emodnet.ec.europa.eu), CC-BY 4.0" |
NCEI Seafloor Sediment Grain-Size Database (NOAA, G00127; bottom_sources='grainsize') |
sediment (global, public-domain samples) | U.S. Government work --- public domain | National Geophysical Data Center (1976), The NGDC Seafloor Sediment Grain Size Database, NOAA NCEI, doi:10.7289/V5G44N6W. (The DECK41 G02094 lithology file is also accepted if supplied.) |
Diesing 2020 global deep-sea seafloor lithology (bottom_sources='diesing') |
sediment (global deep-sea, >500 m) | CC-BY 4.0 | Diesing, M. (2020). Deep-sea sediments of the global ocean. Earth Syst. Sci. Data 12, 3367--3381. doi:10.5194/essd-12-3367-2020; data: PANGAEA doi:10.1594/PANGAEA.911692 |
Pelagic model (bottom_sources='pelagic', depth/latitude classifier) |
sediment (global open-ocean fallback, modelled) | Public domain (first-principles model) | after Diesing (2020) & Berger, W.H. (1974), Deep-sea sedimentation |
| GlobSed total sediment thickness (NOAA NCEI) | sediment thickness (low-frequency seabed) | U.S. Government work --- public domain | Straume, E.O., et al. (2019). GlobSed: Updated total sediment thickness in the world's oceans. Geochem. Geophys. Geosyst. 20, 1756--1772. doi:10.1029/2018GC008115 |
CRUST1.0 global crustal model (bottom_sources='crust1') |
layered seabed Vp/Vs/density (low-frequency) | No formal licence --- verify before commercial use | Laske, G., Masters, G., Ma, Z. & Pasyanos, M. (2013). Update on CRUST1.0 --- a 1-degree global model of Earth's crust. Geophys. Res. Abstr. 15, EGU2013-2658 |
NSIDC Sea Ice Index (surface_sources='seaice') |
sea-ice concentration → elastic ice surface (monthly climatology) | U.S. Government work --- public domain | Fetterer, F., et al. (2017, updated). Sea Ice Index (G02135), NSIDC, doi:10.7265/N5K072F8 |
Natural Earth land polygons (uacpy.plot.plot_bathymetry_map coastline) |
map backdrop | Public domain | none required |
A fetched environment carries its provenance per layer:
env.data_sourcesis a tuple ofDataProvenancerecords, each pairing the dataset (.source) with the actual date and coordinates that fetch returned.uacpy.data.citations(env)prints the required attribution/citation — plus the fetched date/location — for exactly those sources (uacpy.data.citations()prints the full catalogue below).
Questions, bug reports, and contributions are welcome. For matters not suited to a GitHub issue (collaboration proposals, private questions, etc.), the maintainer can be reached at:
@software{uacpy2026,
title = {UACPY: Underwater ACoustics for PYthon},
author = {ErVuL and UACPY Contributors},
year = {2026},
url = {https://github.com/ErVuL/uacpy}
}
