def read_baseline_info(baseline_file, reference_file): """Read date, bperp and/or DOP info Parameters: baseline_file : str, path of bl_list.txt file reference_file : str, path of ifgramStack.h5 file Returns: date_list : list of str in YYMMDD format tbase_list : list of int in days pbase_list : list of float in meter dop_list : None, list of 1D array in size of (3,) """ dop_list = None if baseline_file: date_list, pbase_list, dop_list = pnet.read_baseline_file( baseline_file)[0:3] date_list = ptime.yymmdd(date_list) tbase_list = ptime.date_list2tbase(date_list)[0] elif reference_file: obj = ifgramStack(reference_file) date12_list_all = obj.get_date12_list(dropIfgram=False) date12_list_all = ptime.yymmdd_date12(date12_list_all) m_dates = [i.split('-')[0] for i in date12_list_all] s_dates = [i.split('-')[1] for i in date12_list_all] date_list = sorted(list(set(m_dates + s_dates))) tbase_list = ptime.date_list2tbase(date_list)[0] pbase_list = obj.get_perp_baseline_timeseries( dropIfgram=False).tolist() return date_list, tbase_list, pbase_list, dop_list
def threshold_coherence_based_mst(date12_list, coh_list): """Return a minimum spanning tree of network based on the coherence inverse. Inputs: date12_list - list of string in YYMMDD-YYMMDD format coh_list - list of float, average coherence for each interferogram Output: mst_date12_list - list of string in YYMMDD-YYMMDD format, for MST network of interferograms """ # coh_list --> coh_mat --> weight_mat coh_mat = coherence_matrix(date12_list, coh_list) mask = ~np.isnan(coh_mat) wei_mat = np.zeros(coh_mat.shape) wei_mat[:] = np.inf wei_mat[mask] = 1/coh_mat[mask] # MST path based on weight matrix wei_mat_csr = sparse.csr_matrix(wei_mat) mst_mat_csr = sparse.csgraph.minimum_spanning_tree(wei_mat_csr) # Get date6_list date12_list = ptime.yymmdd_date12(date12_list) m_dates = [date12.split('-')[0] for date12 in date12_list] s_dates = [date12.split('-')[1] for date12 in date12_list] date6_list = ptime.yymmdd(sorted(ptime.yyyymmdd(list(set(m_dates + s_dates))))) # Convert MST index matrix into date12 list [s_idx_list, m_idx_list] = [date_idx_array.tolist() for date_idx_array in sparse.find(mst_mat_csr)[0:2]] mst_date12_list = [] for i in range(len(m_idx_list)): idx = sorted([m_idx_list[i], s_idx_list[i]]) date12 = date6_list[idx[0]]+'-'+date6_list[idx[1]] mst_date12_list.append(date12) return mst_date12_list
def threshold_coherence_based_mst(date12_list, coh_list): """Return a minimum spanning tree of network based on the coherence inverse. Inputs: date12_list - list of string in YYMMDD-YYMMDD format coh_list - list of float, average coherence for each interferogram Output: mst_date12_list - list of string in YYMMDD-YYMMDD format, for MST network of interferograms """ # coh_list --> coh_mat --> weight_mat coh_mat = coherence_matrix(date12_list, coh_list) mask = ~np.isnan(coh_mat) wei_mat = np.zeros(coh_mat.shape) wei_mat[:] = np.inf wei_mat[mask] = 1/coh_mat[mask] # MST path based on weight matrix wei_mat_csr = sparse.csr_matrix(wei_mat) mst_mat_csr = sparse.csgraph.minimum_spanning_tree(wei_mat_csr) # Get date6_list date12_list = ptime.yymmdd_date12(date12_list) m_dates = [date12.split('-')[0] for date12 in date12_list] s_dates = [date12.split('-')[1] for date12 in date12_list] date6_list = ptime.yymmdd(sorted(ptime.yyyymmdd(list(set(m_dates + s_dates))))) # Convert MST index matrix into date12 list [s_idx_list, m_idx_list] = [date_idx_array.tolist() for date_idx_array in sparse.find(mst_mat_csr)[0:2]] mst_date12_list = [] for i in range(len(m_idx_list)): idx = sorted([m_idx_list[i], s_idx_list[i]]) date12 = date6_list[idx[0]]+'-'+date6_list[idx[1]] mst_date12_list.append(date12) return mst_date12_list
def coherence_matrix(date12_list, coh_list, diag_value=np.nan, fill_triangle='both', date_list=None): """Return coherence matrix based on input date12 list and its coherence Inputs: date12_list - list of string in YYMMDD-YYMMDD format coh_list - list of float, average coherence for each interferograms diag_value - number, value to be filled in the diagonal fill_triangle - str, 'both', 'upper', 'lower' Output: coh_matrix - 2D np.array with dimension length = date num np.nan value for interferograms non-existed. 1.0 for diagonal elements """ # Get date list date12_list = ptime.yymmdd_date12(date12_list) if not date_list: m_dates = [date12.split('-')[0] for date12 in date12_list] s_dates = [date12.split('-')[1] for date12 in date12_list] date_list = sorted(list(set(m_dates + s_dates))) date_list = ptime.yymmdd(date_list) date_num = len(date_list) coh_mat = np.zeros([date_num, date_num]) coh_mat[:] = np.nan for date12 in date12_list: date1, date2 = date12.split('-') idx1 = date_list.index(date1) idx2 = date_list.index(date2) coh = coh_list[date12_list.index(date12)] if fill_triangle in ['upper', 'both']: coh_mat[idx1, idx2] = coh # symmetric if fill_triangle in ['lower', 'both']: coh_mat[idx2, idx1] = coh if diag_value is not np.nan: for i in range(date_num): # diagonal value coh_mat[i, i] = diag_value return coh_mat
def select_pairs_sequential(date_list, num_conn=2, date_format=None): """Select Pairs in a Sequential way: For each acquisition, find its num_connection nearest acquisitions in the past time. Reference: Fattahi, H., and F. Amelung (2013), DEM Error Correction in InSAR Time Series, IEEE TGRS, 51(7), 4249-4259. Parameters: date_list - list of str for date num_conn - int, number of sequential connections date_format - str / None, output date format Returns: date12_list - list of str for date12 """ date_list = sorted(date_list) date_inds = list(range(len(date_list))) # Get pairs index list date12_inds = [] for date_ind in date_inds: for i in range(num_conn): if date_ind - i - 1 >= 0: date12_inds.append([date_ind - i - 1, date_ind]) date12_inds = [sorted(i) for i in sorted(date12_inds)] # Convert index into date12 date12_list = [ '{}_{}'.format(date_list[ind12[0]], date_list[ind12[1]]) for ind12 in date12_inds ] # adjust output date format if date_format is not None: if date_format == 'YYYYMMDD': date12_list = ptime.yyyymmdd_date12(date12_list) elif date_format == 'YYMMDD': date12_list = ptime.yymmdd_date12(date12_list) else: raise ValueError( 'un-supported date format: {}!'.format(date_format)) return date12_list
def select_network_candidate(inps): date_list, tbase_list, pbase_list, dop_list = read_baseline_info( baseline_file=inps.baseline_file, reference_file=inps.referenceFile) # Pair selection from reference if inps.referenceFile: log('select initial network from reference file: {}'.format( inps.referenceFile)) stack_obj = ifgramStack(inps.referenceFile) date12_list = stack_obj.get_date12_list(dropIfgram=True) date12_list = ptime.yymmdd_date12(date12_list) # Pais selection from method elif inps.baseline_file: log('select initial network with method: {}'.format(inps.method)) if inps.method == 'all': date12_list = pnet.select_pairs_all(date_list) elif inps.method == 'delaunay': date12_list = pnet.select_pairs_delaunay(date_list, pbase_list, inps.norm) elif inps.method == 'star': date12_list = pnet.select_pairs_star(date_list) elif inps.method == 'sequential': date12_list = pnet.select_pairs_sequential(date_list, inps.connNum) elif inps.method == 'hierarchical': date12_list = pnet.select_pairs_hierarchical( date_list, pbase_list, inps.tempPerpList) elif inps.method == 'mst': date12_list = pnet.select_pairs_mst(date_list, pbase_list) else: raise Exception('Unrecoganized select method: ' + inps.method) log('initial number of interferograms: {}'.format(len(date12_list))) inps.date12_list = date12_list inps.date_list = date_list inps.tbase_list = tbase_list inps.pbase_list = pbase_list inps.dop_list = dop_list return inps
def coherence_matrix(date12_list, coh_list, diag_value=np.nan, fill_triangle='both', date_list=None): """Return coherence matrix based on input date12 list and its coherence Inputs: date12_list - list of string in YYMMDD-YYMMDD format coh_list - list of float, average coherence for each interferograms diag_value - number, value to be filled in the diagonal fill_triangle - str, 'both', 'upper', 'lower' Output: coh_matrix - 2D np.array with dimension length = date num np.nan value for interferograms non-existed. 1.0 for diagonal elements """ # Get date list date12_list = ptime.yymmdd_date12(date12_list) if not date_list: m_dates = [date12.split('-')[0] for date12 in date12_list] s_dates = [date12.split('-')[1] for date12 in date12_list] date_list = sorted(list(set(m_dates + s_dates))) date_list = ptime.yymmdd(date_list) date_num = len(date_list) coh_mat = np.zeros([date_num, date_num]) coh_mat[:] = np.nan for date12 in date12_list: date1, date2 = date12.split('-') idx1 = date_list.index(date1) idx2 = date_list.index(date2) coh = coh_list[date12_list.index(date12)] if fill_triangle in ['upper', 'both']: coh_mat[idx1, idx2] = coh # symmetric if fill_triangle in ['lower', 'both']: coh_mat[idx2, idx1] = coh if diag_value is not np.nan: for i in range(date_num): # diagonal value coh_mat[i, i] = diag_value return coh_mat