This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

User's Guide

The channels stored in this library can be used in two ways: (1) a channel can be applied directly to a user-generated signal, or (2) it can be decompressed for visualizing. Ready-to-use code for performing these functions is available under GitHub. You can also download the MATLAB package here. To install the Python package,

pip install uwa-channels

Applying a channel to an arbitrary signal

  • To pass a signal of your choice through a channel, generate the desired signal in passband, respecting the bandwidth and the sampling rate limits of the chosen channel (see the channel tab).
  • Run replay on the signal.
  • Specify the noise power, and add the output of noisegen to the output of replay at a desired signal-to-noise ratio.
channel = load('blue_1.mat');
noise = load('blue_1_noise.mat');
y = replay(input, fs, array_index, channel);
w = noisegen(size(y), fs, array_index, noise);
r = y + 0.05 * w;
import h5py
from uwa_channels import replay, noisegen
channel = h5py.File("blue_1.mat", "r")
noise = h5py.File("blue_1_noise.mat", "r")
y = replay(input, fs, array_index, channel)
w = noisegen(y.shape, fs, array_index, noise)
r = y + 0.05 * w

A simple example of this process is given in MATLAB and Python. Before running the example code, please read the corresponding README file.

Visualizing a channel

To visualize a channel as a collection of impulse responses evolving over time, you will need to decompress the channel impulse responses via unpack.m. This will produce a new channel matrix that is decompressed (it is larger than the stored original) and contains all the physical effects of delay drifting. The new matrix can be generated at arbitrary sampling rates in time, provided it is no greater than the sampling rate in delay.

A simple example of this process is given in MATLAB and Python. Before running the example code, please read the corresponding README file.

1 - Channel file format specifications

UWA-Channels MAT File Format Specification

The uwa-channels-compatible .mat files must be saved with the following flags:

  • -v7.3 to support large variables and HDF5 file format.
  • -nocompression to accelerate loading speed.

Required Fields

Each .mat file must include the following variables:

h_hat

  • Type: Multi-dimensional complex tensor.
  • Dimensions: [delay, receiver, time]
  • Units:
    • Delay axis: sampled at params.fs_delay [Hz]
    • Time axis: sampled at params.fs_time [Hz]
    • Amplitude: complex baseband impulse response (unitless)
  • Description: The estimated time-varying channel impulse response (TVIR).

params

A structure with the following scalar fields:

FieldTypeUnitDescription
fs_delayscalarHzSampling rate along the delay axis.
fs_timescalarHzSampling rate along the time axis.
fcscalarHzCenter frequency of the signal used during channel estimation.

version

  • Type: Numeric scalar.
  • Description: Dataset format version number (currently 1.0).

Phase / Delay Tracking Fields

Exactly one of theta_hat or phi_hat must be present.

theta_hat (phase tracking only)

  • Type: Numeric matrix, size [receiver, time]
  • Units: Radians
  • Sampling rate: params.fs_delay
  • Description: Time-varying phase correction. In this mode, h_hat contains the drifting impulse response (delay drift is embedded in the taps). Only the phase is tracked separately. The baseband received signal is modeled as:

$$v(t) = \sum_n d(n), h(t, t - nT), e^{j\theta(t)} + z(t)$$

where $d(n)$ is the data symbol, $h(t, \tau)$ is the time-varying impulse response with drifting taps, $T$ is the symbol duration, and $\theta(t)$ is the tracked phase.

phi_hat (delay tracking)

  • Type: Numeric matrix, size [receiver, time]
  • Units: Radians
  • Sampling rate: params.fs_delay
  • Description: Time-varying phase that encodes both phase rotation and delay drift. In this mode, h_hat is static (drift-free). The delay drift is recovered from phi_hat as:

$$\Delta\tau(t) = \frac{\hat\varphi(t)}{2\pi f_c}$$

The unpacking procedure reinserts both the phase (via multiplication by $e^{j\hat\varphi(t)}$) and the delay drift (via interpolation).

Duration constraint

The time dimension of theta_hat or phi_hat and the third dimension of h_hat must span the same duration:

size(theta_hat, 2) / params.fs_delay == size(h_hat, 3) / params.fs_time

Optional Fields

f_resamp

  • Type: Scalar (double precision)
  • Units: Unitless resampling factor
  • Description: A time-invariant resampling factor applied to the output signal. This is typically the inverse of a resampling operation applied to remove the nominal Doppler frequency offset before channel estimation. It is applied after the time-varying convolution.

meta

The meta structure is optional but strongly encouraged. The following fields are recognized by the toolbox:

FieldTypeDescription
descriptionstringFree-text description of the experiment.
nsdscalarSamples per symbol in the delay domain.
nstscalarSamples per symbol in the time domain.
K_1scalarAnti-causal filter length [symbols].
K_2scalarCausal filter length [symbols].
fcscalarCenter frequency [Hz].
element_spacingscalarArray element spacing [m].
verticallogicaltrue if vertical array.
delay_trackinglogicaltrue if delay tracking is enabled (phi_hat present).
limitscalarLower dB limit for plotting.
optimscalarOptimizer used (1: LMS, 2: RLS, 3: SFTF).
muscalarLMS step size (when optim == 1).
lambdascalarForgetting factor (when optim == 2 or 3).
regularizationscalarRegularization factor (when optim == 2 or 3).
Kf_1scalarPLL loop filter coefficient 1.
Kf_2scalarPLL loop filter coefficient 2.
nslrscalarDelay tracking rate (when delay_tracking == true).
codenamestringShort identifier for the channel (e.g., "blue_1").

Users are free to add additional fields to meta to capture experiment-specific metadata.

Noise File Format

Each noise .mat file contains the following fields:

FieldTypeDescription
FsscalarSampling rate at which noise statistics were measured [Hz].
RscalarSignal bandwidth [Hz].
alphascalarStability index of the SαS distribution (2 = Gaussian, < 2 = impulsive).
betatensor [M, M, K]Mixing coefficients for spatiotemporal noise coloring.
fcscalarCenter frequency [Hz].
rms_powervector [M, 1]Per-channel RMS power scaling.
versionscalarNoise struct version number.

The noise generation function noisegen uses the mixing equation:

$$\hat{n}i(nT_s) = \sum{j=0}^{M-1}\sum_{k=0}^{L}\beta_{ij}(kT_s),\eta_j(nT_s - kT_s)$$

where $\eta_j \sim S\alpha S(0, 1, 0)$ are i.i.d. symmetric α-stable innovations. When alpha = 2, this reduces to Gaussian noise.

2 - Code Contribution Guide

Contributing to UWA-Channels (MATLAB & Python)

First off — thank you for considering a contribution! Bug reports, feature requests, documentation improvements, and code changes are all welcome.

This guide explains how to contribute effectively to the two companion repositories hosted at https://github.com/uwa-channels:

RepositoryLanguageMain BranchFolder Layout
uwa-channels/matlabMATLAB (R2021a+)mainsrc/, tests/, examples/
uwa-channels/pythonPython (≥ 3.10)mainuwa_channels/, tests/, docs/

Getting Started

Prerequisites

  • Familiarity with Git, GitHub, Markdown, and either MATLAB or Python.
    Helpful references: GitHub Quickstart, Markdown Guide.

  • Development environment:

    MATLAB repository

    git clone https://github.com/uwa-channels/matlab.git
    

    To run example scripts:

    cd examples
    example_replay
    

    To run tests:

    cd tests
    addpath('../src')
    runtests('testReplay')
    

    Python repository — create a virtual environment and install dependencies:

    git clone https://github.com/uwa-channels/python.git
    cd python
    pip install numpy scipy matplotlib h5py pytest pytest-benchmark pre-commit
    

    To run example scripts:

    PYTHONPATH=src python examples/example_replay.py
    

    To run tests:

    PYTHONPATH=src pytest
    

    To initialize pre-commit:

    pre-commit install
    pre-commit run --all-files
    

Code of Conduct

We expect all contributors to be professional, respectful, and constructive. By participating, you agree to uphold these standards.

Bug Reports, Feature Requests, & Discussions

Bug Reports

  • Search existing issues and pull requests—your bug may already be reported or fixed.
  • Provide a minimal, reproducible example (MATLAB .m file or live script, or a Python snippet), along with:
    • Package versions (uwa_channels.__version__ or MATLAB ver)
    • OS and MATLAB/Python version, if relevant

Feature Requests

Describe both the motivation and the proposed change. Sketch a possible API or workflow if applicable.

Discussions

General Q&A, design ideas, and roadmap conversations belong in GitHub Discussions, not in Issues.

Issue Labels

LabelMeaning
high-priority / low-priorityRelative urgency
good first issueSuitable for newcomers
breaking-changeAPI/behavior change
Milestone assignedPlanned for release

Workflow for Code & Documentation Changes

  1. Fork the repository and clone your fork.
  2. Create a branch from main, named like topic-short-description (lowercase, hyphen-separated).
  3. Develop locally:
    • MATLAB — run runtests('tests') and address Code Analyzer (MLint) warnings.
    • Python — run PYTHONPATH=src pytest frequently.
  4. Write tests for new features or bug fixes.
  5. Document your changes:
    • Use NumPy-style docstrings in Python functions and classes.
    • Use MATLAB help text headers; add usage examples for public APIs.
  6. Commit with clear messages, then push to your fork.
  7. Open a pull request (PR) against main. Mark it as “Draft” if it’s not yet ready for review. Reference any related issues.
  8. Address reviewer feedback. Once all checks pass and approvals are received, a maintainer will merge.

Commit Message Style

We follow a simplified version of Conventional Commits:

<type>(<scope>): <summary>

<body>
  • type ∈ {feat, fix, docs, test, perf, refactor, style, chore, revert}
  • scope identifies the module or subsystem (e.g., io, replay, noisegen)
  • Use imperative mood for the summary (e.g., “add support…” not “added”)
  • Limit the summary to ≤ 50 characters; wrap the body at 72 characters
  • If the change is breaking, begin the body with BREAKING CHANGE:

Examples:

feat(replay): add resampling support for replay channels
fix(io): handle empty .mat files (issue #42)

Coding Standards

MATLAB, follow the MATLAB Style Guide:

  • 4-space indentation; camelCase for functions, PascalCase for classes
  • Each function/class in its own .m file
  • Use arguments blocks for input validation where possible
  • Add unit tests under tests/testPkgName/ using MATLAB Unit Test
  • Vectorize where possible; comment non-obvious logic

Python

  • Formatting is enforced via Black and isort
  • Static analysis via Flake8 and Ruff
  • Use NumPy-style doc strings with LaTeX equations where helpful
  • Keep functions short, prefer clarity to cleverness, and avoid premature optimization

Testing & Continuous Integration

RepositoryLocal Test CommandCI Matrix
PythonPYTHONPATH=src pytestPython 3.10 – 3.12
MATLABruntests('tests')MATLAB R2021a and latest

All CI checks must pass before a pull request is merged.

Release Process (Python only)

Maintainers tag releases using git tag -s vX.Y.Z following Semantic Versioning (SemVer).

Merged PRs are reflected in CHANGELOG.md, with entries auto-generated from commit messages.

Acknowledgments

This guide was inspired by the excellent UnderwaterAcoustics.jl contributing guide, as well as the contribution guidelines from NumPy, SciPy, and MATLAB Style Guide.

Happy hacking – may your channels be peaceful and your SNR high!