Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

Revision 47fa90566ad704bd3ee325752ba9cb3519618b7f authored by Zhang Yunjun on 09 February 2023, 09:05:51 UTC, committed by GitHub on 09 February 2023, 09:05:51 UTC
`view`: fix referencing error while read unwrapPhase* in 2D w/ multilook (#956)
+ view: fix the bug while referencing unwrapPhase* 2D matrix with multilook number>1

+ requirements: pin scipy<1.10 to avoid interpolate error [temporary]

+ circleci: unset strict conda channel priority

+ ionex: update the link
1 parent 1a3e85d
  • Files
  • Changes
  • 3dcbbd7
  • /
  • tests
  • /
  • dem_error.py
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • revision
  • directory
  • content
revision badge
swh:1:rev:47fa90566ad704bd3ee325752ba9cb3519618b7f
directory badge
swh:1:dir:b08dfc0f38095fee369ed565d1207b23236b2dd1
content badge
swh:1:cnt:6bbfe5ed4ac2086b2269f4acad8b8c604b2467b8

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • revision
  • directory
  • content
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
dem_error.py
#!/usr/bin/env python3
# Author: Zhang Yunjun, Nov 2022
"""Test topographic residuel correction due to DEM errors."""


import argparse
import datetime
import math
import sys

import numpy as np
from matplotlib import pyplot as plt

from mintpy.dem_error import estimate_dem_error
from mintpy.utils import ptime, time_func

################################################################################
# truth
delta_z_sim = 50   # meters

# setting: SAR geometry
range_dist = 800e3  # meters
inc_angle = 34      # degree
max_pbase = 500     # meters

# setting: time / acquisition
revisit_time = datetime.timedelta(days=24)
start_date = datetime.datetime(2018, 1, 1)
num_date = 50
ref_ind = 10

# setting: dem_error.py
phase_velocity = False
cond = 1e-8


################################################################################
EXAMPLE = """example:
  $MINTPY_HOME/tests/dem_error.py
  $MINTPY_HOME/tests/dem_error.py --plot
"""

def cmd_line_parse(iargs=None):
    # create parser
    parser = argparse.ArgumentParser(description='Test dem_error.py',
                                     formatter_class=argparse.RawTextHelpFormatter,
                                     epilog=EXAMPLE)
    parser.add_argument('--plot', dest='plot', action='store_true', help='Plot testing results.')

    # parsing
    inps = parser.parse_args(args=iargs)

    return inps


################################################################################
def sim_pbase_and_topo_residual(num_date, delta_z, ref_ind=0,
                                max_pbase=500, inc_angle=34, range_dist=800e3):

    # sim perp baseline TS
    np.random.seed(12138)
    pbase = np.random.rand(num_date) * max_pbase
    pbase -= pbase[ref_ind]

    # sim topo residual phase
    G_geom = pbase / (range_dist * np.sin(np.deg2rad(inc_angle)))
    ts_topo_res = np.dot(G_geom, delta_z_sim)

    return pbase, ts_topo_res


def plot_result(date_list, ts_sim, ts_obs=None, ts_cor=None, model=None):

    dt_list = ptime.date_list2vector(date_list)[0]

    _, ax = plt.subplots(nrows=1, ncols=1, figsize=(12, 4))
    ax.plot(dt_list, ts_sim*100, '--', color='C0', lw=3, label='simulation')
    if ts_obs is not None:
        ax.plot(dt_list, ts_obs*100, '.', color='C1', lw=3, label='observation')
    if ts_cor is not None:
        ax.plot(dt_list, ts_cor*100, 'o',  color='C2', ms=12, fillstyle='none', label='corrected')

    # plot step function
    if model is not None and 'stepDate' in model.keys():
        for step_date in model['stepDate']:
            step_dt = datetime.datetime.strptime(step_date, '%Y%m%d')
            ax.axvline(step_dt, ls='--', color='k')

    # axis format
    ax.set_xlabel('Time')
    ax.set_ylabel('Displacement [cm]')
    ax.legend()
    plt.show()


################################################################################
def test_dem_error_with_linear_defo(date_list, tbase, rel_tol=0.05, plot=False):
    print('Test 1: simple time-series with linear displacement.')

    # setting
    vel_sim = 0.05  # m/yr
    model = {'polynomial' : 1}

    # simulate displacement time-series
    ts_sim = vel_sim * tbase
    ts_sim -= ts_sim[ref_ind]

    # add topo residual
    pbase, ts_topo_res = sim_pbase_and_topo_residual(
        num_date,
        delta_z_sim,
        ref_ind,
        max_pbase=max_pbase,
        inc_angle=inc_angle,
        range_dist=range_dist,
    )

    # observed time-series: displacement + topo res
    ts_obs = ts_sim + ts_topo_res

    # estimate DEM error
    G_defo = time_func.get_design_matrix4time_func(date_list, model)
    G_geom = np.reshape(pbase / (range_dist * np.sin(np.deg2rad(inc_angle))), (-1,1))
    G = np.hstack((G_geom, G_defo))

    delta_z_est, ts_cor = estimate_dem_error(
        ts_obs, G, tbase,
        phase_velocity=phase_velocity,
        cond=cond,
    )[:2]

    # plot
    if plot:
        plot_result(date_list, ts_sim, ts_obs, ts_cor, model)

    # validate
    print(f'Specified DEM error: {delta_z_sim:.2f} m')
    print(f'Estimated DEM error: {delta_z_est[0]:.2f} m')
    assert math.isclose(delta_z_sim, delta_z_est, rel_tol=rel_tol)
    print('Pass.')


def test_dem_error_with_complex_defo(date_list, tbase, rel_tol=0.05, plot=False):
    print('Test 2: complex time-series with highly non-linear displacement.')

    # setting
    model = {'polynomial' : 2, 'stepDate' : ['20190818', '20200812']}

    # simulate displacement time-series
    # run the following to re-generate:
    #   from mintpy.simulation import simulation as sim
    #   ts_sim = sim.sim_variable_timeseries(50)
    ts_sim = np.array([
         0.        , -0.00049281, -0.00098563, -0.00147844, -0.00197125,
        -0.00246407, -0.00295688, -0.00344969, -0.0039425 , -0.00443532,
         0.06961907,  0.08992067,  0.10159181,  0.10972946,  0.11593095,
         0.12090778,  0.12503949,  0.12855262,  0.1315933 ,  0.13426131,
         0.13662781,  0.13874532,  0.14065379,  0.14238422,  0.14396119,
         0.0826078 ,  0.08704312,  0.09147844,  0.09591376,  0.10034907,
         0.1047844 ,  0.10921971,  0.11365503,  0.11809035,  0.12252566,
         0.126961  ,  0.1313963 ,  0.13583162,  0.14026694,  0.14470226,
        -0.01971253, -0.02020534, -0.02069815, -0.02119097, -0.02168378,
        -0.02217659, -0.0226694 , -0.02316222, -0.02365503, -0.02414784,
    ], dtype=np.float32)

    # add topo residual
    pbase, ts_topo_res = sim_pbase_and_topo_residual(
        num_date,
        delta_z_sim,
        ref_ind,
        max_pbase=max_pbase,
        inc_angle=inc_angle,
        range_dist=range_dist,
    )

    # observed time-series: displacement + topo res
    ts_obs = ts_sim + ts_topo_res

    # estimate DEM error
    G_defo = time_func.get_design_matrix4time_func(date_list, model)
    G_geom = np.reshape(pbase / (range_dist * np.sin(np.deg2rad(inc_angle))), (-1,1))
    G = np.hstack((G_geom, G_defo))

    delta_z_est, ts_cor = estimate_dem_error(
        ts_obs, G, tbase,
        phase_velocity=phase_velocity,
        cond=cond,
    )[:2]

    # plot
    if plot:
        plot_result(date_list, ts_sim, ts_obs, ts_cor, model)

    # validate
    print(f'Specified DEM error: {delta_z_sim:.2f} m')
    print(f'Estimated DEM error: {delta_z_est[0]:.2f} m')
    assert math.isclose(delta_z_sim, delta_z_est, rel_tol=rel_tol)
    print('Pass.')


################################################################################
def main(iargs=None):

    print('-'*50)
    print(f'Testing {__file__}')
    inps = cmd_line_parse(iargs)

    # prepare common data: date_list, tbase
    dt_list = [start_date + revisit_time * x for x in range(num_date)]
    date_list = [x.strftime('%Y%m%d') for x in dt_list]

    tbase = np.array(ptime.date_list2tbase(date_list)[0]) / 365.25   # years
    tbase -= tbase[ref_ind]

    # scenario 1 - simple linear deformation
    test_dem_error_with_linear_defo(
        date_list,
        tbase,
        rel_tol=0.05,
        plot=inps.plot,
    )

    # scenario 2 - complex nonlinear deformation (with more relaxed tolerance: 10%)
    test_dem_error_with_complex_defo(
        date_list,
        tbase,
        rel_tol=0.10,
        plot=inps.plot,
    )


################################################################################
if __name__ == '__main__':
    main(sys.argv[1:])
The diff you're trying to view is too large. Only the first 1000 changed files have been loaded.
Showing with 0 additions and 0 deletions (0 / 0 diffs computed)
swh spinner

Computing file changes ...

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API