Esempio n. 1
0
def design_matrix4deformation(inps):
    # Date Info
    ts_obj = timeseries(inps.timeseries_file)
    ts_obj.open()

    # Design matrix - temporal deformation model
    print('-'*80)
    print('correct topographic phase residual (DEM error) (Fattahi & Amelung, 2013, IEEE-TGRS)')
    msg = 'ordinal least squares (OLS) inversion with L2-norm minimization on: phase'
    if inps.phaseVelocity:
        msg += ' velocity'
    if inps.rangeDist.size != 1:
        msg += ' (pixel-wisely)'
    print(msg)

    tbase = np.array(ts_obj.tbase, np.float32) / 365.25

    # 1. Polynomial - 2D matrix in size of (numDate, polyOrder+1)
    print("temporal deformation model: polynomial order = "+str(inps.polyOrder))
    A_def = np.ones((ts_obj.numDate, 1), np.float32)
    for i in range(inps.polyOrder):
        Ai = np.array(tbase**(i+1) / gamma(i+2), np.float32).reshape(-1, 1)
        A_def = np.hstack((A_def, Ai))

    # 2. Step function - 2D matrix in size of (numDate, len(inps.stepFuncDate))
    if inps.stepFuncDate:
        print("temporal deformation model: step functions at "+str(inps.stepFuncDate))
        t_steps = ptime.yyyymmdd2years(inps.stepFuncDate)
        t = np.array(ptime.yyyymmdd2years(ts_obj.dateList))
        for t_step in t_steps:
            Ai = np.array(t > t_step, np.float32).reshape(-1, 1)
            A_def = np.hstack((A_def, Ai))
    print('-'*80)
    return A_def
Esempio n. 2
0
def read_exclude_date(inps, dateListAll):
    # Merge ex_date/startDate/endDate into ex_date
    yy_list_all = ptime.yyyymmdd2years(dateListAll)
    exDateList = []

    # ex_date
    exDateList += ptime.read_date_list(list(inps.excludeDate),
                                       date_list_all=dateListAll)
    if exDateList:
        print('exclude date:' + str(exDateList))

    # startDate
    if inps.startDate:
        print('start date: ' + inps.startDate)
        yy_min = ptime.yyyymmdd2years(ptime.yyyymmdd(inps.startDate))
        for i in range(len(dateListAll)):
            date = dateListAll[i]
            if yy_list_all[i] < yy_min and date not in exDateList:
                print('  remove date: ' + date)
                exDateList.append(date)

    # endDate
    if inps.endDate:
        print('end date: ' + inps.endDate)
        yy_max = ptime.yyyymmdd2years(ptime.yyyymmdd(inps.endDate))
        for i in range(len(dateListAll)):
            date = dateListAll[i]
            if yy_list_all[i] > yy_max and date not in exDateList:
                print('  remove date: ' + date)
                exDateList.append(date)
    exDateList = sorted(list(set(exDateList)))
    return exDateList
Esempio n. 3
0
def read_inps2model(inps, date_list=None):
    """get model info from inps"""
    # check model date limits
    if not date_list:
        date_list = inps.dateList
    dmin, dmax = date_list[0], date_list[-1]
    ymin = ptime.yyyymmdd2years(dmin)
    ymax = ptime.yyyymmdd2years(dmax)

    if inps.step:
        for d_step in inps.step:
            y_step = ptime.yyyymmdd2years(d_step)
            if not (ymin < y_step < ymax):
                raise ValueError(
                    f'input step date "{d_step}" exceed date list min/max: {dmin}, {dmax}'
                )

    if inps.expDict:
        for d_onset in inps.expDict.keys():
            y_onset = ptime.yyyymmdd2years(d_onset)
            if y_onset >= ymax:
                raise ValueError(
                    f'input exp onset date "{d_onset}" >= the last date: {dmax}'
                )

    if inps.logDict:
        for d_onset in inps.logDict.keys():
            y_onset = ptime.yyyymmdd2years(d_onset)
            if y_onset >= ymax:
                raise ValueError(
                    f'input log onset date "{d_onset}" >= the last date: {dmax}'
                )

    model = dict()
    model['polynomial'] = inps.polynomial
    model['periodic'] = inps.periodic
    model['step'] = inps.step
    model['exp'] = inps.expDict
    model['log'] = inps.logDict

    # msg
    print(
        'estimate deformation model with the following assumed time functions:'
    )
    for key, value in model.items():
        print('    {:<10} : {}'.format(key, value))

    if 'polynomial' not in model.keys():
        raise ValueError(
            'linear/polynomial model is NOT included! Are you sure?!')

    # number of parameters
    num_param = (model['polynomial'] + 1 + len(model['periodic']) * 2 +
                 len(model['step']) +
                 sum([len(val) for key, val in model['exp'].items()]) +
                 sum([len(val) for key, val in model['log'].items()]))

    return model, num_param
Esempio n. 4
0
def get_design_matrix4step_func(date_list, step_date_list, seconds=0):
    """design matrix/function model of coseismic velocity estimation
    Parameters: date_list      : list of dates in YYYYMMDD format
                step_date_list : Heaviside step function(s) with date in YYYYMMDD
    Returns:    A              : 2D array of zeros & ones in size of (num_date, num_step)
    """
    num_date = len(date_list)
    num_step = len(step_date_list)
    A = np.zeros((num_date, num_step), dtype=np.float32)

    t = np.array(ptime.yyyymmdd2years(date_list, seconds=seconds))
    t_steps = ptime.yyyymmdd2years(step_date_list)
    for i, t_step in enumerate(t_steps):
        A[:, i] = np.array(t > t_step).flatten()

    return A
Esempio n. 5
0
def get_design_matrix4log_func(date_list, log_dict, seconds=0):
    """design matrix/function model of logarithmic postseismic relaxation estimation

    Reference: Eq. (4) in Hetland et al. (2012, JGR)
    Note that there is a typo in the paper for this equation, based on the MInTS code, it should be:
        Sum_i{ a_i * H(t-Ti) * [1 + log((t-T_i)/tau_i)] }
    instead of the one below shown in the paper:
        Sum_i{ a_i * H(t-Ti) * [1 + log((t)/tau_i)] }
    where:
        a_i         amplitude      of i-th log term
        T_i         onset time     of i-th log term
        tau_i       char time      of i-th log term (relaxation time)
        H(t-T_i)    Heaviside func of i-th log term (ensuring the log func is one-sided)

    Parameters: date_list      : list of dates in YYYYMMDD format
                log_dict       : dict of log func(s) info as:
                                 {{onset_time1} : [{char_time11,...,char_time1N}],
                                  {onset_time2} : [{char_time21,...,char_time2N}],
                                  ...
                                  }
                                 where onset_time is string  in YYYYMMDD format and
                                       char_time  is float32 in decimal days
    Returns:    A              : 2D array of zeros & ones in size of (num_date, num_log)
    """
    num_date = len(date_list)
    num_log  = sum([len(log_dict[x]) for x in log_dict])
    A = np.zeros((num_date, num_log), dtype=np.float32)

    t = np.array(ptime.yyyymmdd2years(date_list, seconds=seconds))
    # loop for onset time(s)
    i = 0
    for log_onset in log_dict.keys():
        # convert string to float in years
        log_T = ptime.yyyymmdd2years(log_onset)

        # loop for charateristic time(s)
        for log_tau in log_dict[log_onset]:
            # convert time from days to years
            log_tau /= 365.25

            olderr = np.seterr(invalid='ignore', divide='ignore')
            A[:, i] = np.array(t > log_T).flatten() * np.nan_to_num(np.log(1 + (t - log_T) / log_tau), nan=0, neginf=0)
            np.seterr(**olderr)
            i += 1

    return A
Esempio n. 6
0
def correct_local_oscilator_drift(fname, rg_dist_file=None, out_file=None):
    print('-'*50)
    print('correct Local Oscilator Drift for Envisat using an empirical model (Marinkovic and Larsen, 2013)')
    print('-'*50)
    atr = readfile.read_attribute(fname)

    # Check Sensor Type
    platform = atr['PLATFORM']
    print('platform: '+platform)
    if not platform.lower() in ['env', 'envisat']:
        print('No need to correct LOD for '+platform)
        return

    # output file name
    if not out_file:
        out_file = '{}_LODcor{}'.format(os.path.splitext(fname)[0], os.path.splitext(fname)[1])

    # Get LOD ramp rate from empirical model
    if not rg_dist_file:
        print('calculate range distance from file metadata')
        rg_dist = get_relative_range_distance(atr)
    else:
        print('read range distance from file: %s' % (rg_dist_file))
        rg_dist = readfile.read(rg_dist_file, datasetName='slantRangeDistance', print_msg=False)[0]
        rg_dist -= rg_dist[int(atr['REF_Y']), int(atr['REF_X'])]
    ramp_rate = np.array(rg_dist * 3.87e-7, np.float32)

    # Correct LOD Ramp for Input fname
    range2phase = -4*np.pi / float(atr['WAVELENGTH'])
    k = atr['FILE_TYPE']
    if k == 'timeseries':
        # read
        obj = timeseries(fname)
        obj.open()
        data = obj.read()

        # correct LOD
        diff_year = np.array(obj.yearList)
        diff_year -= diff_year[obj.refIndex]
        for i in range(data.shape[0]):
            data[i, :, :] -= ramp_rate * diff_year[i]

        # write
        obj_out = timeseries(out_file)
        obj_out.write2hdf5(data, refFile=fname)

    elif k in ['.unw']:
        data, atr = readfile.read(fname)

        dates = ptime.yyyymmdd2years(ptime.yyyymmdd(atr['DATE12'].split('-')))
        dt = dates[1] - dates[0]
        data -= ramp_rate * range2phase * dt

        writefile.write(data, out_file=out_file, metadata=atr)
    else:
        print('No need to correct for LOD for %s file' % (k))
    return out_file
Esempio n. 7
0
def get_design_matrix4exp_func(date_list, exp_dict, seconds=0):
    """design matrix/function model of exponential postseismic relaxation estimation

    Reference: Eq. (5) in Hetland et al. (2012, JGR).
    Note that there is a typo in the paper for this equation, based on the MInTS code, it should be:
        Sum_i{ a_i * H(t-Ti) * [1 - e^(-(t-T_i)/tau_i)] }
    instead of the one below shown in the paper:
        Sum_i{ a_i * H(t-Ti) * [1 - e^(-(t)/tau_i)] }
    where:
        a_i         amplitude      of i-th exp term
        T_i         onset time     of i-th exp term
        tau_i       char time      of i-th exp term (relaxation time)
        H(t-T_i)    Heaviside func of i-th exp term (ensuring the exp func is one-sided)

    Parameters: date_list      : list of dates in YYYYMMDD format
                exp_dict       : dict of exp func(s) info as:
                                 {{onset_time1} : [{char_time11,...,char_time1N}],
                                  {onset_time2} : [{char_time21,...,char_time2N}],
                                  ...
                                  }
                                 where onset_time is string  in YYYYMMDD format and
                                       char_time  is float32 in decimal days
    Returns:    A              : 2D array of zeros & ones in size of (num_date, num_exp)
    """
    num_date = len(date_list)
    num_exp  = sum([len(val) for key, val in exp_dict.items()])
    A = np.zeros((num_date, num_exp), dtype=np.float32)

    t = np.array(ptime.yyyymmdd2years(date_list, seconds=seconds))
    # loop for onset time(s)
    i = 0
    for exp_onset in exp_dict.keys():
        # convert string to float in years
        exp_T = ptime.yyyymmdd2years(exp_onset)

        # loop for charateristic time(s)
        for exp_tau in exp_dict[exp_onset]:
            # convert time from days to years
            exp_tau /= 365.25
            A[:, i] = np.array(t > exp_T).flatten() * (1 - np.exp(-1 * (t - exp_T) / exp_tau))
            i += 1

    return A
Esempio n. 8
0
def get_design_matrix4time_func(date_list, poly_order=2, step_func_dates=[]):
    """get design matrix for temporal deformation model"""
    # temporal baseline in the unit of years
    tbase = ptime.date_list2tbase(date_list)[0]
    tbase = np.array(tbase, dtype=np.float32) / 365.25

    # 1. Polynomial - 2D matrix in size of (numDate, polyOrder+1)
    A_def = np.ones((len(date_list), 1), np.float32)
    for i in range(poly_order):
        Ai = np.array(tbase**(i + 1) / gamma(i + 2), np.float32).reshape(-1, 1)
        A_def = np.hstack((A_def, Ai))

    # 2. Step function - 2D matrix in size of (numDate, len(step_func_dates))
    if step_func_dates:
        t_steps = ptime.yyyymmdd2years(step_func_dates)
        t = np.array(ptime.yyyymmdd2years(date_list))
        for t_step in t_steps:
            Ai = np.array(t > t_step, np.float32).reshape(-1, 1)
            A_def = np.hstack((A_def, Ai))

    return A_def
Esempio n. 9
0
def read_exclude_date(inps, dateListAll):
    # Merge ex_date/startDate/endDate into ex_date
    yy_list_all = ptime.yyyymmdd2years(dateListAll)
    exDateList = []
    # 1. template_file
    if inps.template_file:
        print('read option from template file: ' + inps.template_file)
        inps = read_template2inps(inps.template_file, inps)

    # 2. ex_date
    exDateList += ptime.read_date_list(list(inps.excludeDate),
                                       date_list_all=dateListAll)
    if exDateList:
        print('exclude date:' + str(exDateList))

    # 3. startDate
    if inps.startDate:
        print('start date: ' + inps.startDate)
        yy_min = ptime.yyyymmdd2years(ptime.yyyymmdd(inps.startDate))
        for i in range(len(dateListAll)):
            date = dateListAll[i]
            if yy_list_all[i] < yy_min and date not in exDateList:
                print('  remove date: ' + date)
                exDateList.append(date)

    # 4. endDate
    if inps.endDate:
        print('end date: ' + inps.endDate)
        yy_max = ptime.yyyymmdd2years(ptime.yyyymmdd(inps.endDate))
        for i in range(len(dateListAll)):
            date = dateListAll[i]
            if yy_list_all[i] > yy_max and date not in exDateList:
                print('  remove date: ' + date)
                exDateList.append(date)
    exDateList = list(set(exDateList))
    return exDateList
Esempio n. 10
0
def get_design_matrix4time_func(date_list, model=None, ref_date=None, seconds=0):
    """Design matrix (function model) for time functions parameter estimation.
    Parameters: date_list - list of str in YYYYMMDD format, size=num_date
                model     - dict of time functions, e.g.:
                            {'polynomial' : 2,                    # int, polynomial degree with 1 (linear), 2 (quadratic), 3 (cubic), etc.
                             'periodic'   : [1.0, 0.5],           # list of float, period(s) in years. 1.0 (annual), 0.5 (semiannual), etc.
                             'step'       : ['20061014'],         # list of str, date(s) in YYYYMMDD.
                             'exp'        : {'20181026': [60],    # dict, key for onset time in YYYYMMDD and value for char. times in days.
                                             ...
                                             },
                             'log'        : {'20161231': [80.5],  # dict, key for onset time in YYYYMMDD and value for char. times in days.
                                             '20190125': [100, 200],
                                             ...
                                             },
                             ...
                             }
                ref_date  - reference date from date_list
                seconds   - float or str, acquisition time of the day info in seconds.
    Returns:    A         - 2D array of design matrix in size of (num_date, num_param)
                            num_param = (poly_deg + 1) + 2*len(periodic) + len(steps) + len(exp_taus) + len(log_taus)
    """

    ## prepare time info
    # convert list of date into array of years in float
    yr_diff = np.array(ptime.yyyymmdd2years(date_list, seconds=seconds))

    # reference date
    if ref_date is None:
        ref_date = date_list[0]
    yr_diff -= yr_diff[date_list.index(ref_date)]

    ## construct design matrix A
    # default model value
    if not model:
        model = {'polynomial' : 1}

    # read the models
    poly_deg   = model.get('polynomial', 0)
    periods    = model.get('periodic', [])
    steps      = model.get('step', [])
    exps       = model.get('exp', dict())
    logs       = model.get('log', dict())
    num_period = len(periods)
    num_step   = len(steps)
    num_exp    = sum([len(val) for key, val in exps.items()])
    num_log    = sum([len(val) for key, val in logs.items()])

    num_param = (poly_deg + 1) + (2 * num_period) + num_step + num_exp + num_log
    if num_param <= 1:
        raise ValueError('NO time functions specified!')

    # initialize the design matrix
    num_date = len(yr_diff)
    A = np.zeros((num_date, num_param), dtype=np.float32)
    c0 = 0

    # update linear/polynomial term(s)
    # poly_deg of 0 --> offset
    # poly_deg of 1 --> velocity
    # ...
    c1 = c0 + poly_deg + 1
    A[:, c0:c1] = get_design_matrix4polynomial_func(yr_diff, poly_deg)
    c0 = c1

    # update periodic term(s)
    if num_period > 0:
        c1 = c0 + 2 * num_period
        A[:, c0:c1] = get_design_matrix4periodic_func(yr_diff, periods)
        c0 = c1

    # update coseismic/step term(s)
    if num_step > 0:
        c1 = c0 + num_step
        A[:, c0:c1] = get_design_matrix4step_func(date_list, steps, seconds=seconds)
        c0 = c1

    # update exponential term(s)
    if num_exp > 0:
        c1 = c0 + num_exp
        A[:, c0:c1] = get_design_matrix4exp_func(date_list, exps, seconds=seconds)
        c0 = c1

    # update logarithmic term(s)
    if num_log > 0:
        c1 = c0 + num_log
        A[:, c0:c1] = get_design_matrix4log_func(date_list, logs, seconds=seconds)
        c0 = c1

    return A