Beispiel #1
0
def plot_init_map(ax, d_v, inps, metadata):

    # prepare data
    if inps.wrap:
        if inps.disp_unit_v == 'radian':
            d_v *= inps.range2phase
        d_v = ut.wrap(d_v, wrap_range=inps.wrap_range)

    # Title and Axis Label
    disp_date = inps.dates[inps.init_idx].strftime('%Y-%m-%d')
    inps.fig_title = 'N = {}, Time = {}'.format(inps.init_idx, disp_date)

    # Initial Pixel
    if inps.yx and inps.yx != inps.ref_yx:
        inps.pts_yx = np.array(inps.yx).reshape(-1, 2)
        if inps.lalo:
            inps.pts_lalo = np.array(inps.lalo).reshape(-1, 2)
        else:
            inps.pts_lalo = None
        inps.pts_marker = 'ro'

    # call view.py to plot
    ax, inps, im, cbar = view.plot_slice(ax, d_v, metadata, inps)

    return ax, im
Beispiel #2
0
def get_nonzero_phase_closure(ifgram_file,
                              out_file=None,
                              thres=0.1,
                              unwDatasetName='unwrapPhase'):
    """Calculate/Read number of non-zero phase closure
    Parameters: ifgram_file : string, path of ifgram stack file
                out_file    : string, path of num non-zero phase closure file
    Returns:    num_nonzero_closure : 2D np.array in size of (length, width)
    """
    if not out_file:
        out_file = 'numNonzeroPhaseClosure_{}.h5'.format(unwDatasetName)
    if os.path.isfile(out_file) and readfile.read_attribute(out_file):
        print('1. read number of nonzero phase closure from file: {}'.format(
            out_file))
        num_nonzero_closure = readfile.read(out_file)[0]
    else:
        obj = ifgramStack(ifgram_file)
        obj.open(print_msg=False)
        length, width = obj.length, obj.width

        ref_phase = obj.get_reference_phase(unwDatasetName=unwDatasetName,
                                            dropIfgram=False)
        C = obj.get_design_matrix4triplet(
            obj.get_date12_list(dropIfgram=False))

        # calculate phase closure line by line to save memory usage
        num_nonzero_closure = np.zeros((length, width), np.float32)
        print(
            '1. calculating phase closure of all pixels from dataset - {} ...'.
            format(unwDatasetName))
        line_step = 10
        num_loop = int(np.ceil(length / line_step))
        prog_bar = ptime.progressBar(maxValue=num_loop)
        for i in range(num_loop):
            # read phase
            i0, i1 = i * line_step, min(length, (i + 1) * line_step)
            box = (0, i0, width, i1)
            pha_data = ifginv.read_unwrap_phase(obj,
                                                box,
                                                ref_phase,
                                                unwDatasetName=unwDatasetName,
                                                dropIfgram=False,
                                                print_msg=False)
            # calculate phase closure
            pha_closure = np.dot(C, pha_data)
            pha_closure = np.abs(pha_closure - ut.wrap(pha_closure))
            # get number of non-zero phase closure
            num_nonzero = np.sum(pha_closure >= thres, axis=0)
            num_nonzero_closure[i0:i1, :] = num_nonzero.reshape(i1 - i0, width)
            prog_bar.update(i + 1,
                            every=1,
                            suffix='{}/{} lines'.format((i + 1) * line_step,
                                                        length))
        prog_bar.close()

        atr = dict(obj.metadata)
        atr['FILE_TYPE'] = 'mask'
        atr['UNIT'] = 1
        writefile.write(num_nonzero_closure, out_file=out_file, metadata=atr)
    return num_nonzero_closure
Beispiel #3
0
 def update_time_slider(val):
     """Update Displacement Map using Slider"""
     idx = np.argmin(np.abs(np.array(inps.yearList) - tslider.val))
     disp_date = inps.dates[idx].strftime('%Y-%m-%d')
     ax_v.set_title('N = {n}, Time = {t}'.format(n=idx, t=disp_date))
     d_v = np.array(ts_data[0][idx, :, :])
     if inps.wrap:
         if inps.disp_unit_v == 'radian':
             d_v *= inps.range2phase
         d_v = ut.wrap(d_v, wrap_range=inps.wrap_range)
     im.set_data(d_v)
     fig_v.canvas.draw()
Beispiel #4
0
def correct_unwrap_error(ifgram, C, Dconstraint=True, thres=0.1, alpha=0.25, rcond=1e-5):
    """Estimate unwrapping error from a stack of unwrapped interferometric phase
    Parameters: ifgram : 2D np.array in size of (num_ifgram, num_pixel) of unwrap phase
                C      : 2D np.array in size of (num_triangle, num_ifgram) triangle design matrix
                Dconstraint : bool, apply zero phase jump constraint on ifgrams without unwrapping error.
                    This is disabled in fast option
                thres  : float, threshold of non-zero phase closure beyond which indicates unwrap error
                alpha  : float, Tikhonov factor, regularization parameter
                rcond  : float, cut-off value for least square estimation
    Returns:    ifgram_cor : 2D np.array in size of (num_ifgram, num_pixel) of unwrap phase after correction
                U          : 2D np.array in size of (num_ifgram, num_pixel) of phase jump integer
    Example:    ifgram_cor, U = estimate_unwrap_error(ifgram, C)
    """
    num_tri, num_ifgram = C.shape
    ifgram = ifgram.reshape(num_ifgram, -1)
    U = np.zeros(ifgram.shape, np.float32)

    I = np.eye(num_ifgram, dtype=np.float32)
    A = np.vstack((C, alpha*I))
    # Use Tikhonov regularization (alpha*D0) to solve equation in ill-posed scenario:
    # e.g.: network is not dense enough AND a lot of unwrapping error exist,
    # then A.shape[0] < A.shape[1]: number of unknown > number of observations

    if Dconstraint:
        # get D
        # 1. calculate phase closure for all ifgram triangles --> identy those with unwrap error
        # 2. identy ifgrams involved in at least 1 triangle with unwrap error
        # 3. get D for ifgram 'without any unwrap error' or 'correctly unwrapped'
        pha_closure = np.dot(C, ifgram)
        pha_closure = np.abs(pha_closure - ut.wrap(pha_closure))
        idx_nonzero_closure = (pha_closure >= thres).flatten()
        idx_err_ifgram = np.sum(C[idx_nonzero_closure, :] != 0., axis=0) >= 1.
        D = I[~idx_err_ifgram, :]
        A = np.vstack((A, D))

    # Eq 4.4 (Fattahi, 2015)
    try:
        A_inv = linalg.pinv2(A, rcond=rcond)
        L = np.zeros((A.shape[0], ifgram.shape[1]), np.float32)
        L[0:num_tri, :] = np.dot(C, ifgram) / (-2.*np.pi)
        U = np.round(np.dot(A_inv, L))

    except linalg.LinAlgError:
        pass

    ifgram_cor = ifgram + 2*np.pi*U
    return ifgram_cor, U
Beispiel #5
0
 def update_time_slider(self, val):
     """Update Displacement Map using Slider"""
     idx = np.argmin(np.abs(np.array(self.yearList) - self.tslider.val))
     # update title
     disp_date = self.dates[idx].strftime('%Y-%m-%d')
     self.ax_img.set_title('N = {n}, Time = {t}'.format(n=idx, t=disp_date), fontsize=self.font_size)
     # read data
     data_img = np.array(self.ts_data[0][idx, :, :])
     data_img[self.mask == 0] = np.nan
     if self.wrap:
         if self.disp_unit_img == 'radian':
             data_img *= self.range2phase
         data_img = ut.wrap(data_img, wrap_range=self.wrap_range)
     # update data
     self.img.set_data(data_img)
     self.fig_img.canvas.draw()
     return
Beispiel #6
0
    def plot_init_image(self, img_data):
        # prepare data
        if self.wrap:
            if self.disp_unit_img == 'radian':
                img_data *= self.range2phase
            img_data = ut.wrap(img_data, wrap_range=self.wrap_range)

        # Title and Axis Label
        disp_date = self.dates[self.init_idx].strftime('%Y-%m-%d')
        self.fig_title = 'N = {}, Time = {}'.format(self.init_idx, disp_date)

        # Initial Pixel
        if self.yx and self.yx != self.ref_yx:
            self.pts_yx = np.array(self.yx).reshape(-1, 2)
            if self.lalo:
                self.pts_lalo = np.array(self.lalo).reshape(-1, 2)
            else:
                self.pts_lalo = None

        # call view.py to plot
        self.img, self.cbar_img = view.plot_slice(self.ax_img, img_data, self.atr, self)[2:4]
        return self.img, self.cbar_img
def get_common_region_int_ambiguity(ifgram_file,
                                    cc_mask_file,
                                    water_mask_file=None,
                                    num_sample=100,
                                    dsNameIn='unwrapPhase'):
    """Solve the phase unwrapping integer ambiguity for the common regions among all interferograms
    Parameters: ifgram_file     : str, path of interferogram stack file
                cc_mask_file    : str, path of common connected components file
                water_mask_file : str, path of water mask file
                num_sample      : int, number of pixel sampled for each region
                dsNameIn        : str, dataset name of the unwrap phase to be corrected
    Returns:    common_regions  : list of skimage.measure._regionprops._RegionProperties object
                    modified by adding two more variables:
                    sample_coords : 2D np.ndarray in size of (num_sample, 2) in int64 format
                    int_ambiguity : 1D np.ndarray in size of (num_ifgram,) in int format
    """
    print('-' * 50)
    print(
        'calculating the integer ambiguity for the common regions defined in',
        cc_mask_file)
    # stack info
    stack_obj = ifgramStack(ifgram_file)
    stack_obj.open()
    date12_list = stack_obj.get_date12_list(dropIfgram=True)
    num_ifgram = len(date12_list)
    C = matrix(
        ifgramStack.get_design_matrix4triplet(date12_list).astype(float))
    ref_phase = stack_obj.get_reference_phase(unwDatasetName=dsNameIn,
                                              dropIfgram=True).reshape(
                                                  num_ifgram, -1)

    # prepare common label
    print('read common mask from', cc_mask_file)
    cc_mask = readfile.read(cc_mask_file)[0]
    if water_mask_file is not None and os.path.isfile(water_mask_file):
        water_mask = readfile.read(water_mask_file)[0]
        print('refine common mask based on water mask file', water_mask_file)
        cc_mask[water_mask == 0] = 0

    label_img, num_label = connectComponent.get_large_label(cc_mask,
                                                            min_area=2.5e3,
                                                            print_msg=True)
    common_regions = measure.regionprops(label_img)
    print('number of common regions:', num_label)

    # add sample_coords / int_ambiguity
    print('number of samples per region:', num_sample)
    print('solving the phase-unwrapping integer ambiguity for {}'.format(
        dsNameIn))
    print(
        '\tbased on the closure phase of interferograms triplets (Yunjun et al., 2019)'
    )
    print(
        '\tusing the L1-norm regularzed least squares approximation (LASSO) ...'
    )
    for i in range(num_label):
        common_reg = common_regions[i]
        # sample_coords
        idx = sorted(
            np.random.choice(common_reg.area, num_sample, replace=False))
        common_reg.sample_coords = common_reg.coords[idx, :].astype(int)

        # solve for int_ambiguity
        U = np.zeros((num_ifgram, num_sample))
        if common_reg.label == label_img[stack_obj.refY, stack_obj.refX]:
            print('{}/{} skip calculation for the reference region'.format(
                i + 1, num_label))
        else:
            prog_bar = ptime.progressBar(maxValue=num_sample,
                                         prefix='{}/{}'.format(
                                             i + 1, num_label))
            for j in range(num_sample):
                # read unwrap phase
                y, x = common_reg.sample_coords[j, :]
                unw = ifginv.read_unwrap_phase(stack_obj,
                                               box=(x, y, x + 1, y + 1),
                                               ref_phase=ref_phase,
                                               unwDatasetName=dsNameIn,
                                               dropIfgram=True,
                                               print_msg=False).reshape(
                                                   num_ifgram, -1)

                # calculate closure_int
                closure_pha = np.dot(C, unw)
                closure_int = matrix(
                    np.round(
                        (closure_pha - ut.wrap(closure_pha)) / (2. * np.pi)))

                # solve for U
                U[:, j] = np.round(
                    l1regls(-C, closure_int, alpha=1e-2,
                            show_progress=0)).flatten()
                prog_bar.update(j + 1, every=5)
            prog_bar.close()
        # add int_ambiguity
        common_reg.int_ambiguity = np.median(U, axis=1)
        common_reg.date12_list = date12_list

    #sort regions by size to facilitate the region matching later
    common_regions.sort(key=lambda x: x.area, reverse=True)

    # plot sample result
    fig_size = pp.auto_figure_size(label_img.shape, disp_cbar=False)
    fig, ax = plt.subplots(figsize=fig_size)
    ax.imshow(label_img, cmap='jet')
    for common_reg in common_regions:
        ax.plot(common_reg.sample_coords[:, 1],
                common_reg.sample_coords[:, 0],
                'k.',
                ms=2)
    pp.auto_flip_direction(stack_obj.metadata, ax, print_msg=False)
    out_img = 'common_region_sample.png'
    fig.savefig(out_img, bbox_inches='tight', transparent=True, dpi=300)
    print('saved common regions and sample pixels to file', out_img)

    return common_regions
Beispiel #8
0
def run_unwrap_error_patch(ifgram_file, box=None, mask_file=None, ref_phase=None, fast_mode=False,
                           thres=0.1, dsNameIn='unwrapPhase'):
    """Estimate/Correct unwrapping error in ifgram stack on area defined by box.
    Parameters: ifgram_file : string, ifgramStack file
                box : tuple of 4 int, indicating areas to be read and analyzed
                mask_file : string, file name of mask file for pixels to be analyzed
                ref_pahse : 1D np.array in size of (num_ifgram,) phase value on reference pixel, because:
                    1) phase value stored in pysar is not reference yet
                    2) reference point may be out of box definition
                fast_mode : bool, apply zero jump constraint on ifgrams without unwrapping error.
                thres : float, threshold of non-zero phase closure to be identified as unwrapping error.
    Returns:    pha_data : 3D np.array in size of (num_ifgram_all, box[3]-box[2], box[2]-box[0]),
                    unwrapped phase value after error correction
    """
    # Basic info
    stack_obj = ifgramStack(ifgram_file)
    stack_obj.open(print_msg=False)
    num_ifgram = stack_obj.numIfgram

    # Size Info - Patch
    if box:
        num_row = box[3] - box[1]
        num_col = box[2] - box[0]
    else:
        num_row = stack_obj.length
        num_col = stack_obj.width
    num_pixel = num_row * num_col

    C = stack_obj.get_design_matrix4ifgram_triangle(dropIfgram=True)
    print('number of interferograms: {}'.format(C.shape[1]))
    print('number of triangles: {}'.format(C.shape[0]))

    # read unwrapPhase
    pha_data_all = ifginv.read_unwrap_phase(stack_obj, box, ref_phase,
                                            unwDatasetName=dsNameIn,
                                            dropIfgram=False)
    pha_data = np.array(pha_data_all[stack_obj.dropIfgram, :])

    # mask of pixels to analyze
    mask = np.ones((num_pixel), np.bool_)
    print('number of pixels read: {}'.format(num_pixel))
    # mask 1. mask of water or area of interest
    if mask_file:
        dsNames = readfile.get_dataset_list(mask_file)
        dsName = [i for i in dsNames if i in ['waterMask', 'mask']][0]
        waterMask = readfile.read(mask_file, datasetName=dsName, box=box)[0].flatten()
        mask *= np.array(waterMask, np.bool_)
        del waterMask
        print('number of pixels left after mask: {}'.format(np.sum(mask)))

    # mask 2. mask of pixels without unwrap error: : zero phase closure on all triangles
    print('calculating phase closure of all possible triangles ...')
    pha_closure = np.dot(C, pha_data)
    pha_closure = np.abs(pha_closure - ut.wrap(pha_closure))       # Eq 4.2 (Fattahi, 2015)
    num_nonzero_closure = np.sum(pha_closure >= thres, axis=0)
    mask *= (num_nonzero_closure != 0.)
    del pha_closure
    print('number of pixels left after checking phase closure: {}'.format(np.sum(mask)))

    # mask summary
    num_pixel2proc = int(np.sum(mask))
    if num_pixel2proc > 0:
        ifgram = pha_data[:, mask]
        ifgram_cor = np.array(ifgram, np.float32)
        print('number of pixels to process: {} out of {} ({:.2f}%)'.format(num_pixel2proc, num_pixel,
                                                                           num_pixel2proc/num_pixel*100))

        # correcting unwrap error based on phase closure
        print('correcting unwrapping error ...')
        if fast_mode:
            ifgram_cor = correct_unwrap_error(ifgram, C, Dconstraint=False)[0]

        else:
            prog_bar = ptime.progressBar(maxValue=num_pixel2proc)
            for i in range(num_pixel2proc):
                ifgram_cor[:, i] = correct_unwrap_error(ifgram[:, i], C, Dconstraint=True)[0].flatten()
                prog_bar.update(i+1, every=10, suffix='{}/{}'.format(i+1, num_pixel2proc))
            prog_bar.close()

        pha_data[:, mask] = ifgram_cor
        pha_data_all[stack_obj.dropIfgram, :] = pha_data

    pha_data_all = pha_data_all.reshape(num_ifgram, num_row, num_col)
    num_nonzero_closure = num_nonzero_closure.reshape(num_row, num_col)
    return pha_data_all, num_nonzero_closure