Skip to main content

sidescanpy

DOI

Read, correct, grid and export sidescan sonar data.

Documentation: https://rshomberg-research.github.io/sidescanpy/

Beta. Until 1.0, any 0.x release may change the .ss.h5 file format, the API and the CLI. Keep your raw sonar files, pin the version you use, and expect to re-convert .ss.h5 files after an upgrade. See docs/status.md.

Raw and corrected waterfall of a public EdgeTech line

A public EdgeTech recording (UK JNCC, Open Government Licence), raw on the left and after the bottom-track, TVG and slant-to-ground-range steps on the right.

sidescanpy converts EdgeTech JSF, Klein SDF and XTF surveys into one xarray-based model, stored as a grouped HDF5 file (.ss.h5). On top of that model it provides:

  • Corrections: time-varying gain (spreading + Francois-Garrison absorption), slant-to-ground range, per-sample georeferencing, far-range noise cropping. Every applied step is recorded with its parameters, and radiometric steps can be inverted.
  • Slicing by ping, time, sample, slant or ground range, and bounding box.
  • Gridding onto geographic or UTM rasters (mean, median, max, nearest, IDW), with GeoTIFF output.
  • Targets and datasets: read target catalogs, match targets to pings, and build COCO/YOLO training sets of fixed-size chips or full swaths, in native pixels or real-world meters.
  • Analysis: small functions that measure a dataset (nadir and first bottom return, usable range, TVG model fit, units, beam geometry, navigation segments) and return dataclasses.
  • CLI: sidescan-convert, sidescan-correct, sidescan-export, sidescan-analyze for quick runs over the same API.

Workflows, multi-step reports and figure layouts live in your own project scripts and in examples/, not in the library. examples/project_template/ is a starting point: one script per step, one config per survey, a report after each step (see docs/workflow.md).

Install

Python 3.12 or newer, from PyPI:

pip install "sidescanpy[viz]"
pip install "sidescanpy[viz,maps,geo]"

uv pip install and uv add take the same argument. The second line adds basemaps (cartopy) and GeoTIFF output (rioxarray).

From a checkout, with uv:

uv sync --all-extras
Extra Adds Needed for
viz matplotlib sidescanpy.viz, figures from sidescan-export / sidescan-analyze
maps cartopy land and locator basemaps behind georeferenced plots
geo rioxarray grids.to_geotiff, sidescan-export grid --geotiff
dev pytest, ruff, matplotlib running the tests and linters

Conversion, correction, gridding, analysis and dataset export run without any extra.

Data model

Backscatter is three-dimensional: (ping, channel, sample), with channel=0 port and channel=1 starboard. Each frequency of a survey is its own xr.Dataset; a SideScanSurvey holds the frequencies plus the navigation, attitude, DVL and sensor streams. Across-track coordinates are negative to port and positive to starboard.

Quickstart

from pathlib import Path

from sidescanpy.grids import grid_channel, to_geotiff
from sidescanpy.io import read_and_convert
from sidescanpy.io.hdf5 import read_survey, write_survey
from sidescanpy.processing import (
    apply_tvg,
    compute_geometric_ranges,
    compute_georeferencing,
    interpolate_aux_onto_pings,
    slice_by_range,
)

# Convert raw files to one .ss.h5 survey.
survey = read_and_convert([Path("line_001.jsf")], fmt="jsf")
write_survey(survey, "line_001.ss.h5")

# Each correction is one call, recorded in processing_history.
survey = interpolate_aux_onto_pings(read_survey("line_001.ss.h5"))
survey = apply_tvg(survey, spreading_loss_db=30)
survey = compute_geometric_ranges(survey)
survey = compute_georeferencing(survey)
write_survey(survey, "line_001.corrected.ss.h5", overwrite=True)

# Keep 5-60 m of slant range on one frequency and grid it at 0.5 m.
freq = sorted(survey.frequencies)[0]
ds = slice_by_range(survey.get_frequency(freq).dataset, min_m=5, max_m=60)
raster = grid_channel(ds, resolution_m=0.5)
to_geotiff(raster, "line_001.tif")  # needs the [geo] extra

Every correction also works on a single frequency dataset. To run them from a config file, processing.correct_survey(survey, steps, params) takes the same corrections as a list of step names; for files too large for memory, processing.correct_file(path, steps, chunk_pings=2000) corrects in place, chunk by chunk.

Training dataset from a target catalog

from sidescanpy.export.ml import DatasetSpec, build_target_dataset
from sidescanpy.io import read_target_catalog

# A directory holding the catalog: EdgeTech *.target or Klein Target_*.tgt.
# Klein targets need positions resolved first (sidescanpy.targets.correlate).
_fmt, targets = read_target_catalog("raw/")
spec = DatasetSpec(
    styles=["chip", "dual-swath"], render_level="geometric",
    size_px=1024, swath_size_px=1024, resolution_m=[30 / 1024],
    n_augment=4, jitter_px=460, random_flip=True, swath_fill=True,
    n_background=10, val_fraction=0.2, layout="ultralytics", seed=1,
)
result = build_target_dataset("corrected_ss_h5/", targets, spec, "dataset/")

DatasetSpec round-trips to YAML (DatasetSpec.from_yaml), so a project keeps one config file per dataset.

Command line

Command What it does
sidescan-convert survey JSF/SDF/XTF files to .ss.h5
sidescan-convert targets read a target catalog to targets.json/.csv
sidescan-correct apply correction steps to .ss.h5 files in place
sidescan-export waterfall / grid / track images and rasters
sidescan-export chip COCO/YOLO dataset from a target catalog
sidescan-analyze investigate run every analysis on a file and write a report
sidescan-analyze tvg-fit / nadir / usable-range / ... one analysis at a time
sidescan-analyze segment split a long file into clean sections
sidescan-analyze recommend-config suggest correction and export settings

Every subcommand takes --config file.yaml with the same keys as its flags; unknown keys warn (--strict-config makes them errors). Run any command with --help for its options.

Examples

The documentation site has worked examples and Theory pages (the physics behind each processing step) on openly licensed public recordings, each with its code and the figures it makes. Their scripts are in examples/gallery/ and examples/theory/; sidescanpy.datasets.fetch() downloads the data they use.

The same code on EdgeTech JSF, Benthos XTF and Klein XTF recordings

Three sonars and writers read and TVG-corrected with the same calls: EdgeTech JSF, Benthos XTF (UK JNCC, Open Government Licence) and Klein XTF (USGS, public domain).

examples/ also holds project_template/, a full per-step workflow (convert, analyze, correct, export, dataset) smoke-tested on synthetic data, and atr/, the target-recognition scripts.

Logging

The library logs only at DEBUG and WARNING and never configures handlers. Call sidescanpy.log.configure_logging("INFO") in a script, or pass -v / -q / --log-file to any CLI command.

Documentation

https://rshomberg-research.github.io/sidescanpy/: guide, worked examples and API reference. The site is public; the repository is not yet.

Development

uv sync --all-extras
make test   # unit tests (clears PYTHONPATH)
make lint   # ruff
make docs   # documentation site, runs the gallery (needs every extra: uv sync --all-extras)

Integration tests under tests/integration/ need real survey files and are skipped without them. The public test fixtures are not in the repository either; see docs/development.md. See docs/development.md and CHANGELOG.md.

Citing

If you use sidescanpy in your work, please cite it. The concept DOI 10.5281/zenodo.24121873 always resolves to the latest release; each release also has its own version DOI on Zenodo, which pins the exact code you used. CITATION.cff holds the citation in machine-readable form (GitHub's "Cite this repository" button reads it).

Shomberg, R. sidescanpy: read, correct, grid and export sidescan sonar data. Zenodo. https://doi.org/10.5281/zenodo.24121873

License

MIT. See LICENSE.

Metadata

Release files for sidescanpy 0.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sidescanpy 0.10.1
File Size Uploaded Provenance Actions
sidescanpy-0.10.1.tar.gz 871.4 kB With provenance Details for sidescanpy-0.10.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sidescanpy 0.10.1
File Interpreter ABI Platform Actions
sidescanpy-0.10.1-py3-none-any.whl Python 3 none any Details for sidescanpy-0.10.1-py3-none-any.whl

Total release size: 1.8 MB

Release files / sidescanpy-0.10.1.tar.gz

Download URL sidescanpy-0.10.1.tar.gz
Size 871.4 kB
Tags Source
SHA-256 checksum
How to use checksums
17d2da6955ecd66ec0c713a7ef9cb961e3bc451939ec9bb326b3cc665c90d821
BLAKE2b-256 checksum
How to use checksums
7865dc6067c8ec8484bed6fb45c12b8d914d0820e05415bd4e180648ba986a03
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Release files / sidescanpy-0.10.1-py3-none-any.whl

Download URL sidescanpy-0.10.1-py3-none-any.whl
Size 938.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
07755f79c70ab85c738ac96e431b6fbeb86de38f1cd4ec9743e9dcf299223afa
BLAKE2b-256 checksum
How to use checksums
f7e5163803f3a8636eec8d5f4bfc14e8ae43983280e62d293a7001e2d4beb87c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

Security for sidescanpy 0.10.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for sidescanpy-0.10.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 11, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.10.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page