Skip to main content

whirlwind

Fast Rust-backed 2D InSAR phase unwrapping with Python bindings.

Whirlwind unwraps a complex interferogram and returns both unwrapped phase and connected-component labels. The NISAR comparison shows agreement with production SNAPHU on 2pi ambiguities, with lower runtime in the tested scenes.

The package is whirlwind-insar on PyPI and GitHub; it imports as whirlwind.

Quickstart

git clone https://github.com/scottstanie/whirlwind-insar.git
cd whirlwind-insar
pip install .

Source installs require Python 3.11+ and Rust.

Usage

import whirlwind as ww

unw, conncomp = ww.unwrap(igram, corr, nlooks=10.0, mask=mask)

igram is a complex wrapped interferogram, corr is coherence/correlation in [0, 1], and mask is optional with True for valid pixels.

For noisy scenes, coarsen the solve with downsample (it unwraps a coherently-averaged copy at the given factor to pick each block's 2π cycle, then maps the cycles back onto the full-resolution phase). nlooks stays the effective looks of your input corr — the down-look scaling is handled internally, so you do not raise it yourself:

unw, conncomp = ww.unwrap(igram, corr, nlooks=10.0, mask=mask, downsample=8)

CLI

The whirlwind CLI is at feature parity with the Python unwrap: every knob the Python API exposes (downsample, the bridge post-pass, persistent-scatterer interpolate, Goldstein filtering, and the connected-component cost controls) is available as a flag. Run whirlwind --help for the full list. There are no subcommands: unwrapping is the whole CLI, so all flags go directly to whirlwind (earlier releases used a whirlwind unwrap ... subcommand, which is still accepted with a deprecation note).

Install

Pick whichever is simplest for you:

  1. Prebuilt binary (no Python or toolchain). Download the archive for your platform from the latest release, unpack it, and run the whirlwind executable. A single self-contained binary - handy for MATLAB users driving it via system('whirlwind ...').

  2. With the Python package. The wheel ships a whirlwind console script (the same Rust CLI, entered in-process):

    uvx --from whirlwind-insar whirlwind --help   # zero-install try-out
    pip install whirlwind-insar                   # puts `whirlwind` on PATH
    
  3. From source with Cargo (needs the Rust toolchain):

    cargo install --path crates/whirlwind-cli --locked
    
  4. Docker (see below).

Run

whirlwind \
    --phase wrapped_phase.tif \
    --cor coherence.tif \
    --mask valid_mask.tif \
    --nlooks 10 \
    --out unwrapped_phase.tif

--phase is the wrapped phase in radians: a float32 TIFF, or a flat binary float32 file (see below). --mask is optional; nonzero means valid. When --mask is omitted the CLI uses coherence > 0 (and igram != 0 with --ifg) as the default valid mask, matching the Python API. The CLI writes a connected-component label map by default next to --out (foo.conncomp.tif for TIFF, foo.unw.conncomp for flat .unw); use --conncomp PATH to choose the path or --no-conncomp to skip it.

Flat-binary formats (snaphu / ROI_PAC / isce2 / GAMMA)

Headerless flat-binary rasters from the classic pipelines work directly - no GDAL conversion needed:

# snaphu-style: complex64 .int + amp/cor .cc; width ("line length") on the CLI
whirlwind --ifg pair.int --cor pair.cc --cols 1024 --nlooks 10 --out pair.unw

# ROI_PAC / Stanford: geometry read from the <file>.rsc sidecar automatically
whirlwind --ifg 20150902_20150914.int --cor 20150902_20150914.cc \
    --nlooks 10 --out 20150902_20150914.unw

# isce2 stripmapStack / topsStack: the <file>.xml sidecars provide everything
whirlwind --ifg filt_fine.int --cor filt_fine.cor --nlooks 10 \
    --out filt_fine.unw

# GAMMA: big-endian; width from a .par/.off (or --cols + --big-endian)
whirlwind --ifg pair.diff --ifg-meta pair.off \
    --cor pair.cc --cor-meta pair.off --nlooks 10 --out-format float --out pair.unw
  • --ifg is the raw complex64 interferogram (snaphu COMPLEX_DATA, i.e. numpy.tofile() of a complex64 array); --phase also accepts flat float32 (snaphu FLOAT_DATA). Exactly one of the two is given.
  • --cor may be single-band float32 (isce2 .cor, GAMMA .cc) or the two-band line-interleaved amplitude+correlation "rmg" layout (snaphu's default, ROI_PAC .cc): the band count is detected from the file size and the correlation is read from the second channel, exactly as snaphu does. --cor-format alt-sample covers snaphu's sample-interleaved variant.
  • --cols (alias --width) is snaphu's "line length" / ROI_PAC WIDTH; the row count always comes from the file size. A <file>.rsc or <file>.xml next to each input supplies it automatically (and, for isce2, the dtype, band count, scheme, and byte order). Use --ifg-meta, --phase-meta, or --cor-meta when the sidecar is not next to that input.
  • Output is chosen by extension (override with --out-format): .tif → TIFF; .unw → two-band amp+phase rmg (snaphu's default output layout); anything else → flat float32 phase. Conncomp follows the output style by default: u16 TIFF for TIFF outputs, or one-byte-per-pixel flat for flat outputs (the snaphu/isce2 convention). Flat outputs keep the input's byte order.
  • --mask also accepts snaphu-style flat byte masks (nonzero = valid).

For noisy scenes, coarsen the solve with --downsample (as in the Python API); the integration-component --no-bridge-able re-leveling pass runs by default:

whirlwind --phase wrapped_phase.tif --cor coherence.tif \
    --mask valid_mask.tif --nlooks 10 --downsample 8 \
    --out unwrapped_phase.tif

The CLI is pure Rust (no GDAL), so it also runs from a container. Pull the prebuilt image (published to the GitHub Container Registry by CI), or build it locally:

docker pull ghcr.io/scottstanie/whirlwind-insar:main   # prebuilt, or:
docker build -t ghcr.io/scottstanie/whirlwind-insar .  # build locally

docker run --rm -v "$PWD:/data" ghcr.io/scottstanie/whirlwind-insar \
    --phase /data/wrapped.tif --cor /data/cor.tif --nlooks 10 \
    --out /data/unw.tif

Dolphin

Dolphin can select Whirlwind as an unwrap method:

dolphin unwrap --unwrap-options.unwrap-method whirlwind ...

See the Dolphin docs for the rest of the Dolphin workflow.

Development

uv sync
uv run maturin develop --release
uv run pytest python/tests
cargo test --workspace

More

Repository Layout

  • python/whirlwind: Python API.
  • crates/whirlwind-core: Rust algorithms.
  • crates/whirlwind-py: PyO3 bindings.
  • crates/whirlwind-cli: CLI binary.
  • docs: reference docs.
  • scripts: benchmarks and development utilities.

License

Licensed under either the BSD 3-Clause License or the Apache License, Version 2.0, at your option. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whirlwind_insar-0.3.0.tar.gz (245.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

whirlwind_insar-0.3.0-cp311-abi3-win_amd64.whl (1.6 MB view details)

Uploaded CPython 3.11+Windows x86-64

whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_x86_64.whl (2.0 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_aarch64.whl (1.7 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.8 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.5 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

whirlwind_insar-0.3.0-cp311-abi3-macosx_11_0_arm64.whl (1.4 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

whirlwind_insar-0.3.0-cp311-abi3-macosx_10_12_x86_64.whl (1.7 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file whirlwind_insar-0.3.0.tar.gz.

File metadata

  • Download URL: whirlwind_insar-0.3.0.tar.gz
  • Upload date:
  • Size: 245.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for whirlwind_insar-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4e5adb9ef64495c1b207f72c92bb9e55b913514fdf15d8b6cc81291c4127ec9c
MD5 3227ee8c3dd350776f19a5210c54bac8
BLAKE2b-256 2b962379ee7354456123014c51592fe25e91aebfe026a9168cbf96a4e0fd1c54

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0.tar.gz:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 236cbe23fb1909f49787f4b5b497f177d7605501e49a3cde267aed9c4b959591
MD5 d809b67e318b08a395c628f3b073a5a8
BLAKE2b-256 2b92abf10492d9e008571db9286d0206b7eedb3b2eefa97084652d2f7c55a852

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-win_amd64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6a4fbca87420fb656d16bd7a3dc7ead57baa9398589a7a4fe634ad60a7eee796
MD5 5fddcc3e417118857794b2388a97e048
BLAKE2b-256 687b37d36bafc277c649f3a52711128fd3649d678d87733a3c629fd66eb3e342

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 162b91dd9840f98877360023bc3fbf54b587fa7e33b3975050ae4c831554efbb
MD5 4c774b712b0d3435495c988a42487473
BLAKE2b-256 535b48e9c629f2feb9e493a90b43de99e8a6cd7d74496085c121f5c7deddc621

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 eff97a8b52cbdfa420e5dbdb674731601acfbacdc54a5a86806022280870acfe
MD5 ef34fd266948689aea1f9bf0845400ba
BLAKE2b-256 92de328552c1193fa681f8a9e5b85020b586a3236c90b9786a8aa0cf23cb1823

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e1d5c2610af8d6c2e9651f2b253f5af09ecf45891a2363ad830b69ec1f1909cd
MD5 51fbc3177f479e96f7cc053fcdfaf2e8
BLAKE2b-256 bd23eb742f6c7001236f4c80c65d92f8cb0037ab07fc49fbb852620736399c30

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 17208ce06ec4f0686fb5d84361dc0b6dd48aee0f1dac02900481bb17df60b366
MD5 0aa8a927a315084e4fa7dea97d9a4326
BLAKE2b-256 182e70d64717b468b20bc4fc07c4c99cde4e8331fa24d514807a524ed43a847b

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whirlwind_insar-0.3.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for whirlwind_insar-0.3.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 6f1fd0836f0a3b895a5de42d825b38cc1051f2b9db2ff43df451d6362d4e1bf1
MD5 337dd74790f8c40bfe8979ded21d289c
BLAKE2b-256 ab6a304ed3870c772f9d5c5b5c515ae9a905266a35fe73e481ce2cac57d62e9d

See more details on using hashes here.

Provenance

The following attestation bundles were made for whirlwind_insar-0.3.0-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on scottstanie/whirlwind-insar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page