Rust-backed 2D phase unwrapper for InSAR (`import whirlwind`)
Project description
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-insaron PyPI and GitHub; it imports aswhirlwind.
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 unwrap --help for the full list.
Install
Pick whichever is simplest for you:
-
Prebuilt binary (no Python or toolchain). Download the archive for your platform from the latest release, unpack it, and run the
whirlwindexecutable. A single self-contained binary - handy for MATLAB users driving it viasystem('whirlwind unwrap ...'). -
With the Python package. The wheel ships a
whirlwindconsole 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
-
From source with Cargo (needs the Rust toolchain):
cargo install --path crates/whirlwind-cli --locked
-
Docker (see below).
Run
whirlwind unwrap \
--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 unwrap --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 unwrap --ifg 20150902_20150914.int --cor 20150902_20150914.cc \
--nlooks 10 --out 20150902_20150914.unw
# isce2 stripmapStack / topsStack: the <file>.xml sidecars provide everything
whirlwind unwrap --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 unwrap --ifg pair.diff --ifg-meta pair.off \
--cor pair.cc --cor-meta pair.off --nlooks 10 --out-format float --out pair.unw
--ifgis the raw complex64 interferogram (snaphuCOMPLEX_DATA, i.e.numpy.tofile()of a complex64 array);--phasealso accepts flat float32 (snaphuFLOAT_DATA). Exactly one of the two is given.--cormay 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-samplecovers snaphu's sample-interleaved variant.--cols(alias--width) is snaphu's "line length" / ROI_PACWIDTH; the row count always comes from the file size. A<file>.rscor<file>.xmlnext to each input supplies it automatically (and, for isce2, the dtype, band count, scheme, and byte order). Use--ifg-meta,--phase-meta, or--cor-metawhen 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. --maskalso 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 unwrap --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 unwrap \
--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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file whirlwind_insar-0.2.1.tar.gz.
File metadata
- Download URL: whirlwind_insar-0.2.1.tar.gz
- Upload date:
- Size: 239.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6a891236dd32a2d74dec45aa18348ab934e484928d8ca764ce74689d20a9df9
|
|
| MD5 |
b1681c8dec889821a1fbeaf0f5f37e6c
|
|
| BLAKE2b-256 |
42889f1a983bbf459d4a9393ccc2b9b886919963506510f73c24ee2822015f5e
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1.tar.gz:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1.tar.gz -
Subject digest:
d6a891236dd32a2d74dec45aa18348ab934e484928d8ca764ce74689d20a9df9 - Sigstore transparency entry: 1791459106
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-win_amd64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-win_amd64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.11+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9abeda26076255abb5784142ebc7afb8586c25ec8cdc10e7f6f335073d5190a
|
|
| MD5 |
ac97010d1c177199153d7baaa8144972
|
|
| BLAKE2b-256 |
5c26fdd3e1ee07355eaf0123a9055da85dcb8e4eb42e0a7a0a08fd5aaa6720fc
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-win_amd64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-win_amd64.whl -
Subject digest:
b9abeda26076255abb5784142ebc7afb8586c25ec8cdc10e7f6f335073d5190a - Sigstore transparency entry: 1791460312
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.11+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc7e3d84ef8b85950a54394895e41148779eaa32b0ffcea9547bed39f273349e
|
|
| MD5 |
65b5baea54a945069848b9015295f1a2
|
|
| BLAKE2b-256 |
b720e462dc6a0f9415baab12054942e9c757985af6ab208d67eec784ab9ea383
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
bc7e3d84ef8b85950a54394895e41148779eaa32b0ffcea9547bed39f273349e - Sigstore transparency entry: 1791459811
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.11+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c124932f0cb98cb4bc89cf83af7110757252d799266f1a7f79ca60f7f52aefe0
|
|
| MD5 |
4615fb7d600de2908325506c4c8a37ea
|
|
| BLAKE2b-256 |
6e4cf3259ddf51b0b84b6245e56227d65e39593ebf8c987b1b9a0a3c4c8cb5b4
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_aarch64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-musllinux_1_2_aarch64.whl -
Subject digest:
c124932f0cb98cb4bc89cf83af7110757252d799266f1a7f79ca60f7f52aefe0 - Sigstore transparency entry: 1791460535
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d819c96f17368b1ae50cbedcf16deef17d73216ccaaeee5aed302d7c049a0f5e
|
|
| MD5 |
accd4b6b60f85267fab1b78fd0c43460
|
|
| BLAKE2b-256 |
0e3db3889515df91c51256b2cbb9874e33869421323cff47419dbf474487de1c
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
d819c96f17368b1ae50cbedcf16deef17d73216ccaaeee5aed302d7c049a0f5e - Sigstore transparency entry: 1791460007
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.11+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a1d621db17ed46f0de58136935fa07d0b53e01f3312d719d23fcc95b49bd250
|
|
| MD5 |
cd4bf7fc0e74ef853441331ed5dc5fac
|
|
| BLAKE2b-256 |
6e88b1d034ac201f7a1d0f05d32fce9e37af92ca80a1c68520dd958044544c30
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
0a1d621db17ed46f0de58136935fa07d0b53e01f3312d719d23fcc95b49bd250 - Sigstore transparency entry: 1791459506
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.11+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e0873cd6c55944e6652afbbb2dac4a3a0b49fcc75b7b837107e2f5349b3d530
|
|
| MD5 |
9ef3d4d038c4a6d83abe77312d65b9ba
|
|
| BLAKE2b-256 |
e7d7216b74d84c467bac271620222eab287bf25a53550f6fb0cd17c1d1ba4ac3
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-macosx_11_0_arm64.whl -
Subject digest:
9e0873cd6c55944e6652afbbb2dac4a3a0b49fcc75b7b837107e2f5349b3d530 - Sigstore transparency entry: 1791460783
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type:
File details
Details for the file whirlwind_insar-0.2.1-cp311-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: whirlwind_insar-0.2.1-cp311-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.11+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57348b569f0ae3bffdd4bd7e150d2db990c6681f58d15c8e33224bb41ce01996
|
|
| MD5 |
cdd3fd9c6b46b4f30a8e83ed7ed869a4
|
|
| BLAKE2b-256 |
9e4d304fa4be8c27d2b706fea0433307d7c94f5c7b612f267280d85997bc5baa
|
Provenance
The following attestation bundles were made for whirlwind_insar-0.2.1-cp311-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on scottstanie/whirlwind-insar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
whirlwind_insar-0.2.1-cp311-abi3-macosx_10_12_x86_64.whl -
Subject digest:
57348b569f0ae3bffdd4bd7e150d2db990c6681f58d15c8e33224bb41ce01996 - Sigstore transparency entry: 1791461063
- Sigstore integration time:
-
Permalink:
scottstanie/whirlwind-insar@9b262307b5810cf4c42437abcfbac5916d91a700 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/scottstanie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b262307b5810cf4c42437abcfbac5916d91a700 -
Trigger Event:
push
-
Statement type: