GithubHelp home page GithubHelp logo

isce-framework / snaphu-py Goto Github PK

View Code? Open in Web Editor NEW
33.0 9.0 10.0 477 KB

A simple Python wrapper for SNAPHU

License: Apache License 2.0

CMake 1.80% Python 98.20%
insar phase-unwrapping radar remote-sensing sar synthetic-aperture-radar

snaphu-py's Introduction

snaphu-py

CI codecov Conda Version PyPI - Version OS

A simple Python wrapper for the Statistical-Cost, Network-Flow Algorithm for Phase Unwrapping (SNAPHU)

Installation

Install with conda

You can install snaphu-py with conda using

$ conda install -c conda-forge snaphu

Install with pip

You can install snaphu-py with pip using

$ pip install snaphu

Install from source

To install snaphu-py from source, you will need:

  • Python 3.9 or newer + pip
  • A C compiler

The latest source code can be installed using

$ pip install git+https://github.com/isce-framework/snaphu-py.git

Alternatively, clone the repository (be sure to use the --recursive flag to fetch the Git submodules) and install the local copy using

$ git clone --recursive https://github.com/isce-framework/snaphu-py.git
$ cd snaphu-py
$ pip install .

Note

Editable installs are experimentally supported, with some caveats and configuration. See here for details.

Usage

Basic usage

The main interface is the snaphu.unwrap function, which takes input interferogram and coherence arrays and returns the unwrapped phase and connected component labels.

The inputs may be NumPy arrays or any other type of object that supports a similar interface (h5py Datasets, Zarr Arrays, etc).

The following example illustrates basic usage:

import numpy as np
import snaphu

# Simulate a 512x512 interferogram containing a simple diagonal phase ramp with multiple
# fringes.
y, x = np.ogrid[-3:3:512j, -3:3:512j]
igram = np.exp(1j * np.pi * (x + y))

# Sample coherence for an interferogram with no noise.
corr = np.ones(igram.shape, dtype=np.float32)

# Unwrap using the 'SMOOTH' cost mode and 'MCF' initialization method.
unw, conncomp = snaphu.unwrap(igram, corr, nlooks=1.0, cost="smooth", init="mcf")

The wrapped and unwrapped phase are shown below.

Working with geospatial raster data

Optional support for working with geospatial raster data is provided via the snaphu.io.Raster class, which implements a NumPy-like interface for accessing raster data in GDAL-compatible formats.

This functionality requires the rasterio package.

import snaphu

# Open the input interferogram and coherence rasters as well as a water mask.
igram = snaphu.io.Raster("igram.tif")
corr = snaphu.io.Raster("corr.tif")
mask = snaphu.io.Raster("mask.tif")

# Create output rasters to store the unwrapped phase & connected component labels with
# the same shape, driver, CRS/geotransform, etc as the input interferogram raster.
unw = snaphu.io.Raster.create("unw.tif", like=igram, dtype="f4")
conncomp = snaphu.io.Raster.create("conncomp.tif", like=igram, dtype="u4")

# Unwrap and store the results in the `unw` and `conncomp` rasters.
snaphu.unwrap(igram, corr, nlooks=50.0, mask=mask, unw=unw, conncomp=conncomp)

The wrapped1 and unwrapped phase for an example case are shown below.

snaphu.io.Raster implements Python's context manager protocol, so the above snippet could also be written as:

import snaphu

# Open the input rasters and create output rasters as context managers. The data will be
# flushed and the files closed upon exiting the 'with' block. (Note that this syntax
# requires Python 3.10 or newer -- see https://github.com/python/cpython/issues/56991.)
with (
    snaphu.io.Raster("igram.tif") as igram,
    snaphu.io.Raster("corr.tif") as corr,
    snaphu.io.Raster("mask.tif") as mask,
    snaphu.io.Raster.create("unw.tif", like=igram, dtype="f4") as unw,
    snaphu.io.Raster.create("conncomp.tif", like=igram, dtype="u4") as conncomp,
):
    # Unwrap and store the results in the `unw` and `conncomp` rasters.
    snaphu.unwrap(igram, corr, nlooks=50.0, mask=mask, unw=unw, conncomp=conncomp)

This has the advantage of ensuring that the raster datasets are flushed and closed upon exiting the with block.

Tiling and parallelism

The interferogram may be partitioned into multiple (possibly overlapping) regularly-sized rectangular blocks, each of which is unwrapped independently before being reassembled. This tiling strategy can significantly improve unwrapping runtime and reduce peak memory utilization, but may also introduce phase discontinuities between tiles. In order to mitigate such tiling artifacts, choosing a substantial overlap between tiles is recommended.

Multiple tiles may be unwrapped simultaneously in parallel processes.

The following example demonstrates tiled unwrapping using multiple processes:

import numpy as np
import snaphu

# Simulate a 2048x2048 interferogram containing a simple diagonal phase ramp with many
# fringes.
y, x = np.ogrid[-12:12:2048j, -12:12:2048j]
igram = np.exp(1j * np.pi * (x + y))

# Sample coherence for an interferogram with no noise.
corr = np.ones(igram.shape, dtype=np.float32)

# Unwrap using a 4x4 grid of tiles in parallel using 8 processes.
unw, conncomp = snaphu.unwrap(
    igram, corr, nlooks=1.0, ntiles=(4, 4), tile_overlap=256, nproc=8
)

The wrapped and unwrapped phase are shown below.

FAQ

Why isn't [some configuration parameter] exposed?

The full set of SNAPHU parameters includes >100 configurable options. This project takes a pragmatic (and somewhat opinionated) approach to managing this complexity. Only the most commonly manipulated parameters are exposed.

If there's an option that's not currently supported that you'd like to see added to the interface, feel free to open an issue requesting the addition.

What version of SNAPHU is used?

Our goal is to support the latest available SNAPHU release. The SNAPHU version used by the library can be obtained using

>>> import snaphu
>>> print(snaphu.get_snaphu_version())

What platforms are supported?

Unix-like systems (e.g. Linux, macOS) are supported. Installation on Windows is not currently supported.

Copyright

Copyright (c) 2023 California Institute of Technology ("Caltech"). U.S. Government sponsorship acknowledged.

All rights reserved.

License

This software is licensed under your choice of BSD-3-Clause or Apache-2.0 licenses. The exact terms of each license can be found in the accompanying LICENSE-BSD-3-Clause and LICENSE-Apache-2.0 files, respectively.

SPDX-License-Identifier: BSD-3-Clause OR Apache-2.0

Note

The SNAPHU source code (which is included as a Git submodule) is subject to different license terms, the details of which can be found here. In particular, note that parts of the SNAPHU codebase are subject to terms that prohibit commercial use.

Footnotes

  1. InSAR product processed by ASF DAAC HyP3 2023 using GAMMA software. Contains modified Copernicus Sentinel data 2023, processed by ESA. โ†ฉ

snaphu-py's People

Contributors

dependabot[bot] avatar gmgunter avatar pre-commit-ci[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

snaphu-py's Issues

[Bug]: Snaphu crashing with parallelization options

I was testing out the parallelization options through dolphin, where I specified n_parallel_jobs = 2 and n_parallel_tiles = (2,2), half of the pairs are processed before I encounter this error:

snaphu v2.0.6
14 parameters input from file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu-regrow-conncomps.config.3azoqy6v.txt (14 lines total)
Reading unwrapped phase from file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.unw.kmu6glh6.f4
Reading interferogram magnitude from file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.mag.852wqywg.f4
Reading byte mask from file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.mask.1c69a87q.u1
No weight file specified.  Assuming uniform weights
Reading correlation data from file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.corr.j52o8wvj.f4
Calculating smooth-solution cost parameters
Growing connected component mask
Writing connected components to file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.conncomp.8t07h1t7.u4 as 4-byte unsigned ints
Program snaphu done
Elapsed processor time:   0:00:08.00
Elapsed wall clock time:  0:00:09
Assembling tiles
Traceback (most recent call last):
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/snaphu/_snaphu.py", line 89, in run_snaphu
    subprocess.run(args, stderr=subprocess.PIPE, check=True, text=True)
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/subprocess.py", line 571, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/snaphu/snaphu', '-f', '/u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu.config.hvxqxzjp.txt']' returned non-zero exit status 1.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/u/trappist-r0/ssangha/DISP_work/Hawaii/test_packages/calval-DISP/dolphin_PSTworkflow/pst_dolphin_workflow.py", line 368, in <module>
    access_cslcs(inp)
  File "/u/trappist-r0/ssangha/DISP_work/Hawaii/test_packages/calval-DISP/dolphin_PSTworkflow/pst_dolphin_workflow.py", line 355, in access_cslcs
    unwrapping.run(
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/_log.py", line 118, in wrapper
    result = f(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/workflows/unwrapping.py", line 75, in run
    unwrapped_paths, conncomp_paths = unwrap.run(
                                      ^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/_log.py", line 118, in wrapper
    result = f(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/unwrap/_unwrap.py", line 154, in run
    _unw_path, _cc_path = fut.result()
                          ^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/unwrap/_unwrap.py", line 244, in unwrap
    return unwrap_snaphu_py(
           ^^^^^^^^^^^^^^^^^
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/dolphin/unwrap/_snaphu_py.py", line 108, in unwrap_snaphu_py
    snaphu.unwrap(
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/snaphu/_unwrap.py", line 603, in unwrap
    run_snaphu(config_file)
  File "/u/trappist-r0/ssangha/conda_installation/stable_mach14_2022/envs/dolphin-env/lib/python3.11/site-packages/snaphu/_snaphu.py", line 92, in run_snaphu
    raise RuntimeError(errmsg) from e
RuntimeError: WARNING: Tile overlap is small (may give bad results)
Can't open file /u/trappist-r0/ssangha/DISP_work/Hawaii/dolphin/test3_phass_hawaii_des/dolphin_output/stitched_interferograms/scratch/snaphu_tiles_10495/tmptile_snaphu.unw.ag1dtgj7.f4_0_0.3366_regions
Abort

I should mention I was able to run through just fine with n_parallel_jobs = 1 and n_parallel_tiles = (1,1)

Please advise on how I may be able to facilitate debugging actions here. Many thanks!

Relevant environment versioning details:
snaphu = 0.2.0
dolphin commit hash = 071917c1651adba34593a4bd9647543a7f5af913

Snaphu crashes when using interferograms/correlation with `nan` as nodata

Running with files that have nans:

$ python  test_unw.py

snaphu v2.0.6
17 parameters input from file /tmp/tmphnxev295/snaphu.conf (17 lines total)
Creating temporary directory /tmp/tmphnxev295/snaphu_tiles_7086
Unwrapping tile at row 0, column 0 (pid 7105)
Unwrapping tile at row 0, column 1 (pid 7122)
Unwrapping tile at row 0, column 2 (pid 7132)
Unwrapping tile at row 1, column 0 (pid 7279)
Terminated
(mapping-311) [staniewi@aurora snaphu-py]$

When I changed nans to 0s, it does not crash.

Possibly fix: add a np.nan_to_num in the copy_blockwise call, since we're already copying the file from the user-provided reader into a memmap?

[Feature Request]: pipe `snaphu`'s logging through the `logging` module

The current version runs snaphu in a subprocess and only captures stderr. Snaphu's logging all goes to stdout:

$ python test_conncomp_regrow.py > std_out.log
(mapping-311) staniewi:snaphu-py$ cat std_out.log
$ cat std_out.log

snaphu v2.0.6
19 parameters input from file /var/folders/hw/sj9hl8555s36n00t812twvcr0000gq/T/tmpl49af4b1/snaphu.conf (19 lines total)
Creating temporary directory /var/folders/hw/sj9hl8555s36n00t812twvcr0000gq/T/tmpl49af4b1/snaphu_tiles_23572
Unwrapping tile at row 0, column 0 (pid 23575)
Unwrapping tile at row 0, column 1 (pid 23577)
... (etc)

It would be nice to pipe this through python's logging so the application calling snaphu has better control of the formatting/location of the logs.

Multiple possible solutions here: https://stackoverflow.com/questions/4417546/constantly-print-subprocess-output-while-process-is-running

Problems with phase unwrapping results using snaphu-py

Hi,

I am using snaphu-py to unwrap interferometric phase obtained from hyp3. I am running into a couple of issues with the unwrapping results:

  1. Background values seems incorrect
    I notice that some background areas not covered by signal get unwrapped to incorrect phase values.

  2. Water mask does not seem to be applied
    I provide a water mask raster to the snaphu.unwrap function, but this does not seem to have an effect - masked areas still get unwrapped instead of being excluded.

the command I use:
unw, conncomp = snaphu.unwrap(igram_data, corr, nlooks=1.0, mask=mask, ntiles=(4, 4), tile_overlap=256, nproc=8)

the wrapped phase:
image
the result:
image
conncomp file:
image

I would be grateful if you could give me some advice.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.