def get_los_geometry(self, insar_obj, print_msg=False): lat, lon = self.get_stat_lat_lon(print_msg=print_msg) # get LOS geometry if isinstance(insar_obj, str): # geometry file atr = readfile.read_attribute(insar_obj) coord = ut.coordinate(atr, lookup_file=insar_obj) y, x = coord.geo2radar(lat, lon, print_msg=print_msg)[0:2] box = (x, y, x + 1, y + 1) inc_angle = readfile.read(insar_obj, datasetName='incidenceAngle', box=box, print_msg=print_msg)[0][0, 0] az_angle = readfile.read(insar_obj, datasetName='azimuthAngle', box=box, print_msg=print_msg)[0][0, 0] head_angle = ut.azimuth2heading_angle(az_angle) elif isinstance(insar_obj, dict): # use mean inc/head_angle from metadata inc_angle = ut.incidence_angle(insar_obj, dimension=0, print_msg=print_msg) head_angle = float(insar_obj['HEADING']) # for old reading of los.rdr band2 data into headingAngle directly if (head_angle + 180.) > 45.: head_angle = ut.azimuth2heading_angle(head_angle) else: raise ValueError( 'input insar_obj is neight str nor dict: {}'.format(insar_obj)) return inc_angle, head_angle
def transect_lalo(z, atr, start_lalo, end_lalo, interpolation='nearest'): """Extract 2D matrix (z) value along the line [start_lalo, end_lalo]""" coord = ut.coordinate(atr) [y0, y1] = coord.lalo2yx([start_lalo[0], end_lalo[0]], coord_type='lat') [x0, x1] = coord.lalo2yx([start_lalo[1], end_lalo[1]], coord_type='lon') transect = transect_yx(z, atr, [y0, x0], [y1, x1], interpolation) return transect
def plot(self): # Figure 1 self.fig = plt.figure(self.figname, figsize=self.fig_size) # Axes 1 - Image self.ax_img = self.fig.add_axes([0.05, 0.1, 0.4, 0.8]) view_cmd = self.view_cmd.format(self.img_file) d_img, atr, inps_img = view.prep_slice(view_cmd) if self.yx: inps_img.pts_yx = np.array(self.yx).reshape(-1, 2) inps_img.pts_marker = 'r^' inps_img.print_msg = self.print_msg self.ax_img = view.plot_slice(self.ax_img, d_img, atr, inps_img)[0] # coordinate info self.coord = ut.coordinate(atr) self.fig_coord = inps_img.fig_coord # Axes 2 - coherence matrix self.ax_mat = self.fig.add_axes([0.55, 0.125, 0.40, 0.75]) if self.yx: self.plot_coherence_matrix4pixel(self.yx) # Link the canvas to the plots. self.cid = self.fig.canvas.mpl_connect('button_press_event', self.update_coherence_matrix) if self.disp_fig: plt.show() return
def main(argv): if len(sys.argv) < 3: usage() sys.exit(1) lat = float(argv[0]) lon = float(argv[1]) try: trans_file = argv[2] except: trans_file = ut.get_lookup_file() try: radar_file = argv[3] except: radar_file = 'INPUTS/ifgramStack.h5' atr_rdr = readfile.read_attribute(radar_file) print('input geo coord: lat=%.4f, lon=%.4f' % (lat, lon)) coord = ut.coordinate(atr_rdr, lookup_file=trans_file) y, x = coord.geo2radar(np.array(lat), np.array(lon))[0:2] print('corresponding radar coord: y=%d, x=%d' % (y, x)) return
def read_network_info(inps): k = readfile.read_attribute(inps.ifgram_file)['FILE_TYPE'] if k != 'ifgramStack': raise ValueError('input file {} is not ifgramStack: {}'.format(inps.ifgram_file, k)) obj = ifgramStack(inps.ifgram_file) obj.open(print_msg=inps.print_msg) inps.date12_list = obj.get_date12_list(dropIfgram=False) date12_kept = obj.get_date12_list(dropIfgram=True) inps.ex_date12_list = sorted(list(set(inps.date12_list) - set(date12_kept))) inps.date_list = obj.get_date_list(dropIfgram=False) vprint('number of all interferograms: {}'.format(len(inps.date12_list))) vprint('number of dropped interferograms: {}'.format(len(inps.ex_date12_list))) vprint('number of kept interferograms: {}'.format(len(inps.date12_list) - len(inps.ex_date12_list))) vprint('number of acquisitions: {}'.format(len(inps.date_list))) if inps.lalo: if not inps.lookup_file: lookup_file = os.path.join(os.path.dirname(inps.ifgram_file), 'geometry*.h5') inps.lookup_file = ut.get_lookup_file(filePattern=lookup_file) coord = ut.coordinate(obj.metadata, lookup_file=inps.lookup_file) inps.yx = coord.geo2radar(inps.lalo[0], inps.lalo[1])[0:2] if not inps.yx: inps.yx = (obj.refY, obj.refX) vprint('plot initial coherence matrix at reference pixel: {}'.format(inps.yx)) return inps
def subset_input_dict2box(subset_dict, meta_dict): """Convert subset inputs dict into box in radar and/or geo coord. Inputs: subset_dict : dict, including the following 4 objects: subset_x : list of 2 int, subset in x direction, default=None subset_y : list of 2 int, subset in y direction, default=None subset_lat : list of 2 float, subset in lat direction, default=None subset_lon : list of 2 float, subset in lon direction, default=None meta_dict : dict, including the following items: 'WIDTH' : int 'LENGTH': int 'X_FIRST' : float, optional 'Y_FIRST' : float, optional 'X_STEP' : float, optional 'Y_STEP' : float, optional Outputs: # box defined by 4-tuple of number, defining (left, upper, right, lower) coordinate, # (UL_X, UL_Y, LR_X, LR_Y ) pixel_box : 4-tuple of int, in pixel unit - 1 geo_box : 4-tuple of float, in lat/lon unit - degree None if file is in radar coordinate. example: subset_dict = {'subset_x': None, 'subset_y': None, 'subset_lat': [30.5, 31.0], 'subset_lon': [130.0, 131.0]} subset_dict = {'subset_x': [100, 1100], 'subset_y': [2050, 2550], 'subset_lat': None, 'subset_lon': None} pixel_box = subset_input_dict2box(subset_dict, pysar_meta_dict)[0] pixel_box, geo_box = subset_input_dict2box(subset_dict, pysar_meta_dict) """ # Data Coverage width = int(float(meta_dict['WIDTH'])) length = int(float(meta_dict['LENGTH'])) # Use subset_lat/lon input if existed, priority: lat/lon > y/x > len/wid coord = ut.coordinate(meta_dict) if subset_dict['subset_lat']: sub_y = coord.lalo2yx(subset_dict['subset_lat'], coord_type='latitude') elif subset_dict['subset_y']: sub_y = subset_dict['subset_y'] else: sub_y = [0, length] if subset_dict['subset_lon']: sub_x = coord.lalo2yx(subset_dict['subset_lon'], coord_type='longitude') elif subset_dict['subset_x']: sub_x = subset_dict['subset_x'] else: sub_x = [0, width] # Get subset box in y/x sub_x = sorted(sub_x) sub_y = sorted(sub_y) pixel_box = (sub_x[0], sub_y[0], sub_x[1], sub_y[1]) # Get subset box in lat/lon from subset box in y/x geo_box = coord.box_pixel2geo(pixel_box) return pixel_box, geo_box
def reference_point_attribute(atr, y, x): atrNew = dict() atrNew['REF_Y'] = str(y) atrNew['REF_X'] = str(x) coord = ut.coordinate(atr) if 'X_FIRST' in atr.keys(): atrNew['REF_LAT'] = str(coord.yx2lalo(y, coord_type='y')) atrNew['REF_LON'] = str(coord.yx2lalo(x, coord_type='x')) return atrNew
def compute_xy(lat, lon): lat_data = round(float(lat), 4) lon_data = round(float(lon), 4) data_box = (float(attributes['X_FIRST']), float(attributes['Y_FIRST']), lon_data, lat_data) xy = ut.coordinate(attributes).box_geo2pixel(data_box) return str(xy[2]), str(xy[3])
def read_aux_subset2inps(inps): # Convert All Inputs into subset_y/x/lat/lon # Input Priority: subset_y/x/lat/lon > reference > template > tight if all(not i for i in [inps.subset_x, inps.subset_y, inps.subset_lat, inps.subset_lon]): # 1. Read subset info from Reference File if inps.reference: ref_atr = readfile.read_attribute(inps.reference) pix_box, geo_box = get_coverage_box(ref_atr) print('using subset info from ' + inps.reference) # 2. Read subset info from template options elif inps.template_file: pix_box, geo_box = read_subset_template2box(inps.template_file) print('using subset info from ' + inps.template_file) # 3. Use subset from tight info elif inps.tight: inps.lookup_file = ut.get_lookup_file(inps.lookup_file) if not inps.lookup_file: raise Exception( 'No lookup file found! Can not use --tight option without it.' ) atr_lut = readfile.read_attribute(inps.lookup_file) coord = ut.coordinate(atr_lut) if 'Y_FIRST' in atr_lut.keys(): rg_lut = readfile.read(inps.lookup_file, datasetName='range')[0] rg_unique, rg_pos = np.unique(rg_lut, return_inverse=True) idx_row, idx_col = np.where( rg_lut != rg_unique[np.bincount(rg_pos).argmax()]) pix_box = (np.min(idx_col) - 10, np.min(idx_row) - 10, np.max(idx_col) + 10, np.max(idx_row) + 10) geo_box = coord.box_pixel2geo(pix_box) del rg_lut else: lat = readfile.read(inps.lookup_file, datasetName='latitude')[0] lon = readfile.read(inps.lookup_file, datasetName='longitude')[0] geo_box = (np.nanmin(lon), np.nanmax(lat), np.nanmax(lon), np.nanmin(lat)) pix_box = None del lat, lon else: raise Exception('No subset inputs found!') # Update subset_y/x/lat/lon inps = subset_box2inps(inps, pix_box, geo_box) return inps
def metadata_radar2geo(atr_in, res_obj, print_msg=True): """update metadata for radar to geo coordinates""" atr = dict(atr_in) atr['LENGTH'] = res_obj.length atr['WIDTH'] = res_obj.width atr['Y_STEP'] = res_obj.laloStep[0] atr['X_STEP'] = res_obj.laloStep[1] if 'Y_FIRST' in atr_in.keys(): #roipac, gamma atr['Y_FIRST'] = res_obj.SNWE[1] atr['X_FIRST'] = res_obj.SNWE[2] else: #isce, doris atr['Y_FIRST'] = res_obj.SNWE[1] - res_obj.laloStep[0] / 2. atr['X_FIRST'] = res_obj.SNWE[2] - res_obj.laloStep[1] / 2. atr['Y_UNIT'] = 'degrees' atr['X_UNIT'] = 'degrees' # Reference point from y/x to lat/lon if 'REF_Y' in atr.keys(): coord = ut.coordinate(atr_in, lookup_file=res_obj.file) ref_lat, ref_lon = coord.radar2geo(np.array(int(atr['REF_Y'])), np.array(int(atr['REF_X'])), print_msg=False)[0:2] if ~np.isnan(ref_lat) and ~np.isnan(ref_lon): ref_y = int( np.rint( (ref_lat - float(atr['Y_FIRST'])) / float(atr['Y_STEP']))) ref_x = int( np.rint( (ref_lon - float(atr['X_FIRST'])) / float(atr['X_STEP']))) atr['REF_LAT'] = str(ref_lat) atr['REF_LON'] = str(ref_lon) atr['REF_Y'] = str(ref_y) atr['REF_X'] = str(ref_x) if print_msg: print('update REF_LAT/LON/Y/X') else: warnings.warn( "original reference pixel is out of .trans file's coverage. Continue." ) try: atr.pop('REF_Y') atr.pop('REF_X') except: pass try: atr.pop('REF_LAT') atr.pop('REF_LON') except: pass return atr
def compute_lalo(x, y, all_data=False): try: x_data = int(float(x)) except: x_data = 0 try: y_data = int(float(y)) except: y_data = 0 data_box = (0, 0, x_data, y_data) lalo = ut.coordinate(attributes).box_pixel2geo(data_box) formatted_lalo = [str(round(num, 2)) for num in lalo] if all_data: return formatted_lalo else: return formatted_lalo[2], formatted_lalo[3]
def plot_transect_location(ax, inps): print('plot profile line in the 1st input file') data0, atr0 = readfile.read(inps.file[0]) ax.imshow(data0) coord = ut.coordinate(atr0) if inps.start_lalo and inps.end_lalo: [y0, y1] = coord.lalo2yx([inps.start_lalo[0], inps.end_lalo[0]], coord_type='lat') [x0, x1] = coord.lalo2yx([inps.start_lalo[1], inps.end_lalo[1]], coord_type='lon') inps.start_yx = [y0, x0] inps.end_yx = [y1, x1] ax.plot([inps.start_yx[1], inps.end_yx[1]], [inps.start_yx[0], inps.end_yx[0]], 'ro-') ax.set_xlim(0, np.shape(data0)[1]) ax.set_ylim(np.shape(data0)[0], 0) ax.set_title('Transect Line in ' + inps.file[0]) # Status bar def format_coord(x, y): col = int(x) row = int(y) if 0 <= col < data0.shape[1] and 0 <= row < data0.shape[0]: z = data0[row, col] if 'X_FIRST' in atr0.keys(): lat = coord.yx2lalo(row, coord_type='row') lon = coord.yx2lalo(col, coord_type='col') return 'lon=%.4f, lat=%.4f, x=%.0f, y=%.0f, value=%.4f' % ( lon, lat, x, y, z) else: return 'x=%.0f, y=%.0f, value=%.4f' % (x, y, z) else: return 'x=%.0f, y=%.0f' % (x, y) ax.format_coord = format_coord return
def main(argv): if len(sys.argv) < 3: usage() sys.exit(1) y = int(argv[0]) x = int(argv[1]) print('input radar coord: y/azimuth=%d, x/range=%d' % (y, x)) try: trans_file = argv[2] except: trans_file = ut.get_lookup_file() try: radar_file = argv[3] except: radar_file = 'INPUTS/ifgramStack.h5' atr_rdr = readfile.read_attribute(radar_file) coord = ut.coordinate(atr_rdr, lookup_file=trans_file) lat, lon = coord.radar2geo(np.array(y), np.array(x))[0:2] print('corresponding geo coord: lat=%.4f, lon=%.4f' % (lat, lon)) return
def read_subset_box(inpsDict): # Read subset info from template inpsDict['box'] = None inpsDict['box4geo_lut'] = None pix_box, geo_box = subset.read_subset_template2box( inpsDict['template_file'][0]) # Grab required info to read input geo_box into pix_box try: lookupFile = [ glob.glob(str(inpsDict['pysar.load.lookupYFile']))[0], glob.glob(str(inpsDict['pysar.load.lookupXFile']))[0] ] except: lookupFile = None try: pathKey = [ i for i in datasetName2templateKey.values() if i in inpsDict.keys() ][0] file = glob.glob(str(inpsDict[pathKey]))[0] atr = readfile.read_attribute(file) except: atr = dict() geocoded = None if 'Y_FIRST' in atr.keys(): geocoded = True else: geocoded = False # Check conflict if geo_box and not geocoded and lookupFile is None: geo_box = None print(('WARNING: pysar.subset.lalo is not supported' ' if 1) no lookup file AND' ' 2) radar/unkonwn coded dataset')) print('\tignore it and continue.') if not geo_box and not pix_box: return inpsDict # geo_box --> pix_box coord = ut.coordinate(atr, lookup_file=lookupFile) if geo_box is not None: pix_box = coord.bbox_geo2radar(geo_box) pix_box = coord.check_box_within_data_coverage(pix_box) print('input bounding box of interest in lalo: {}'.format(geo_box)) print('box to read for datasets in y/x: {}'.format(pix_box)) # Get box for geocoded lookup table (for gamma/roipac) box4geo_lut = None if lookupFile is not None: atrLut = readfile.read_attribute(lookupFile[0]) if not geocoded and 'Y_FIRST' in atrLut.keys(): geo_box = coord.bbox_radar2geo(pix_box) box4geo_lut = ut.coordinate(atrLut).bbox_geo2radar(geo_box) print('box to read for geocoded lookup file in y/x: {}'.format( box4geo_lut)) inpsDict['box'] = pix_box inpsDict['box4geo_lut'] = box4geo_lut return inpsDict
def read_init_info(inps): # Time Series Info ts_file0 = inps.timeseries_file[0] atr = readfile.read_attribute(ts_file0) inps.key = atr['FILE_TYPE'] if inps.key == 'timeseries': obj = timeseries(ts_file0) elif inps.key == 'giantTimeseries': obj = giantTimeseries(ts_file0) elif inps.key == 'HDFEOS': obj = HDFEOS(ts_file0) else: raise ValueError('input file is {}, not timeseries.'.format(inps.key)) obj.open() if not inps.file_label: inps.file_label = [ str(i) for i in list(range(len(inps.timeseries_file))) ] # default mask file if not inps.mask_file and 'masked' not in ts_file0: dir_name = os.path.dirname(ts_file0) if 'Y_FIRST' in atr.keys(): inps.mask_file = os.path.join(dir_name, 'geo_maskTempCoh.h5') else: inps.mask_file = os.path.join(dir_name, 'maskTempCoh.h5') if not os.path.isfile(inps.mask_file): inps.mask_file = None # date info inps.date_list = obj.dateList if inps.start_date: inps.date_list = [ i for i in inps.date_list if int(i) >= int(inps.start_date) ] if inps.end_date: inps.date_list = [ i for i in inps.date_list if int(i) <= int(inps.end_date) ] inps.num_date = len(inps.date_list) inps.dates, inps.yearList = ptime.date_list2vector(inps.date_list) (inps.ex_date_list, inps.ex_dates, inps.ex_flag) = read_exclude_date(inps.ex_date_list, inps.date_list) # initial display index if obj.metadata['REF_DATE'] in inps.date_list: inps.ref_idx = inps.date_list.index(obj.metadata['REF_DATE']) else: inps.ref_idx = 0 if inps.ref_date: inps.ref_idx = inps.date_list.index(inps.ref_date) if not inps.init_idx: if inps.ref_idx < inps.num_date / 2.: inps.init_idx = -3 else: inps.init_idx = 3 # Display Unit (inps.disp_unit, inps.unit_fac) = pp.scale_data2disp_unit(metadata=atr, disp_unit=inps.disp_unit)[1:3] # Read Error List inps.error_ts = None inps.ex_error_ts = None if inps.error_file: error_fileContent = np.loadtxt(inps.error_file, dtype=bytes).astype(str) inps.error_ts = error_fileContent[:, 1].astype( np.float) * inps.unit_fac if inps.ex_date_list: e_ts = inps.error_ts[:] inps.ex_error_ts = e_ts[inps.ex_flag == 0] inps.error_ts = e_ts[inps.ex_flag == 1] # Zero displacement for 1st acquisition if inps.zero_first: inps.zero_idx = min(0, np.min(np.where(inps.ex_flag)[0])) # default lookup table file if not inps.lookup_file: inps.lookup_file = ut.get_lookup_file('./INPUTS/geometryRadar.h5') inps.coord = ut.coordinate(atr, inps.lookup_file) # size and lalo info inps.pix_box, inps.geo_box = subset.subset_input_dict2box(vars(inps), atr) inps.pix_box = inps.coord.check_box_within_data_coverage(inps.pix_box) inps.geo_box = inps.coord.box_pixel2geo(inps.pix_box) # Out message data_box = (0, 0, obj.width, obj.length) print('data coverage in y/x: ' + str(data_box)) print('subset coverage in y/x: ' + str(inps.pix_box)) print('data coverage in lat/lon: ' + str(inps.coord.box_pixel2geo(data_box))) print('subset coverage in lat/lon: ' + str(inps.geo_box)) print( '------------------------------------------------------------------------' ) # reference pixel if not inps.ref_lalo and 'REF_LAT' in atr.keys(): inps.ref_lalo = (float(atr['REF_LAT']), float(atr['REF_LON'])) if inps.ref_lalo: if inps.ref_lalo[1] > 180.: inps.ref_lalo[1] -= 360. inps.ref_yx = inps.coord.geo2radar(inps.ref_lalo[0], inps.ref_lalo[1], print_msg=False)[0:2] if not inps.ref_yx: inps.ref_yx = [int(atr['REF_Y']), int(atr['REF_X'])] # Initial Pixel Coord if inps.lalo: inps.yx = inps.coord.geo2radar(inps.lalo[0], inps.lalo[1], print_msg=False)[0:2] try: inps.lalo = inps.coord.radar2geo(inps.yx[0], inps.yx[1], print_msg=False)[0:2] except: inps.lalo = None # Flip up-down / left-right if inps.auto_flip: inps.flip_lr, inps.flip_ud = pp.auto_flip_direction(atr) # display unit ans wrap # if wrap_step == 2*np.pi (default value), set disp_unit_v = radian; # otherwise set disp_unit_v = disp_unit inps.disp_unit_v = inps.disp_unit if inps.wrap: inps.range2phase = -4. * np.pi / float(atr['WAVELENGTH']) if 'cm' == inps.disp_unit.split('/')[0]: inps.range2phase /= 100. elif 'mm' == inps.disp_unit.split('/')[0]: inps.range2phase /= 1000. elif 'm' == inps.disp_unit.split('/')[0]: inps.range2phase /= 1. else: raise ValueError('un-recognized display unit: {}'.format( inps.disp_unit)) if (inps.wrap_range[1] - inps.wrap_range[0]) == 2 * np.pi: inps.disp_unit_v = 'radian' inps.vlim = inps.wrap_range inps.cbar_label = 'Displacement [{}]'.format(inps.disp_unit_v) return inps, atr
def main(iargs=None): inps = cmd_line_parse(iargs) # 1. Extract the common area of two input files # Basic info atr1 = readfile.read_attribute(inps.file[0]) atr2 = readfile.read_attribute(inps.file[1]) if any('X_FIRST' not in i for i in [atr1, atr2]): raise Exception('ERROR: Not all input files are geocoded.') k1 = atr1['FILE_TYPE'] print('Input 1st file is ' + k1) # Common AOI in lalo west, east, south, north = get_overlap_lalo(atr1, atr2) lon_step = float(atr1['X_STEP']) lat_step = float(atr1['Y_STEP']) width = int(round((east - west) / lon_step)) length = int(round((south - north) / lat_step)) # Read data in common AOI: LOS displacement, heading angle, incident angle u_los = np.zeros((2, width * length)) heading = [] incidence = [] for i in range(len(inps.file)): fname = inps.file[i] print('---------------------') print('reading ' + fname) atr = readfile.read_attribute(fname) coord = ut.coordinate(atr) [x0, x1] = coord.lalo2yx([west, east], coord_type='lon') [y0, y1] = coord.lalo2yx([north, south], coord_type='lat') V = readfile.read(fname, box=(x0, y0, x1, y1))[0] u_los[i, :] = V.flatten(0) heading_angle = float(atr['HEADING']) if heading_angle < 0.: heading_angle += 360. print('heading angle: ' + str(heading_angle)) heading_angle *= np.pi / 180. heading.append(heading_angle) inc_angle = float(ut.incidence_angle(atr, dimension=0)) inc_angle *= np.pi / 180. incidence.append(inc_angle) # 2. Project displacement from LOS to Horizontal and Vertical components # math for 3D: cos(theta)*Uz - cos(alpha)*sin(theta)*Ux + sin(alpha)*sin(theta)*Uy = Ulos # math for 2D: cos(theta)*Uv - sin(alpha-az)*sin(theta)*Uh = Ulos #Uh_perp = 0.0 # This could be easily modified to support multiple view geometry # (e.g. two adjcent tracks from asc & desc) to resolve 3D # Design matrix A = np.zeros((2, 2)) for i in range(len(inps.file)): A[i, 0] = np.cos(incidence[i]) A[i, 1] = np.sin(incidence[i]) * np.sin(heading[i] - inps.azimuth) A_inv = np.linalg.pinv(A) u_vh = np.dot(A_inv, u_los) u_v = np.reshape(u_vh[0, :], (length, width)) u_h = np.reshape(u_vh[1, :], (length, width)) # 3. Output # Attributes atr = atr1.copy() atr['WIDTH'] = str(width) atr['LENGTH'] = str(length) atr['X_FIRST'] = str(west) atr['Y_FIRST'] = str(north) atr['X_STEP'] = str(lon_step) atr['Y_STEP'] = str(lat_step) print('---------------------') outname = inps.outfile[0] print('writing vertical component to file: ' + outname) writefile.write(u_v, out_file=outname, metadata=atr) outname = inps.outfile[1] print('writing horizontal component to file: ' + outname) writefile.write(u_h, out_file=outname, metadata=atr) print('Done.') return
def read_reference_input(inps): atr = readfile.read_attribute(inps.file) length = int(atr['LENGTH']) width = int(atr['WIDTH']) inps.go_reference = True if inps.reset: remove_reference_pixel(inps.file) inps.outfile = inps.file inps.go_reference = False return inps print('-' * 50) # Check Input Coordinates # Read ref_y/x/lat/lon from reference/template # priority: Direct Input > Reference File > Template File if inps.template_file: print('reading reference info from template: ' + inps.template_file) inps = read_template_file2inps(inps.template_file, inps) if inps.reference_file: print('reading reference info from reference: ' + inps.reference_file) inps = read_reference_file2inps(inps.reference_file, inps) # Convert ref_lat/lon to ref_y/x coord = ut.coordinate(atr, lookup_file=inps.lookup_file) if inps.ref_lat and inps.ref_lon: (inps.ref_y, inps.ref_x) = coord.geo2radar(np.array(inps.ref_lat), np.array(inps.ref_lon))[0:2] print('input reference point in lat/lon: {}'.format( (inps.ref_lat, inps.ref_lon))) if inps.ref_y and inps.ref_x: print('input reference point in y/x: {}'.format( (inps.ref_y, inps.ref_x))) # Do not use ref_y/x outside of data coverage if (inps.ref_y and inps.ref_x and not (0 <= inps.ref_y <= length and 0 <= inps.ref_x <= width)): inps.ref_y = None inps.ref_x = None raise ValueError('input reference point is OUT of data coverage!') # Do not use ref_y/x in masked out area if inps.ref_y and inps.ref_x and inps.maskFile: print('mask: ' + inps.maskFile) mask = readfile.read(inps.maskFile, datasetName='mask')[0] if mask[inps.ref_y, inps.ref_x] == 0: inps.ref_y = None inps.ref_x = None msg = 'input reference point is in masked OUT area defined by {}!'.format( inps.maskFile) raise ValueError(msg) # Select method if not inps.ref_y or not inps.ref_x: print('no input reference y/x.') if not inps.method: # Use existing REF_Y/X if no ref_y/x input and no method input if not inps.force and 'REF_X' in atr.keys(): print('REF_Y/X exists in input file, skip updating.') print('REF_Y: ' + atr['REF_Y']) print('REF_X: ' + atr['REF_X']) inps.outfile = inps.file inps.go_reference = False # method to select reference point elif inps.coherenceFile and os.path.isfile(inps.coherenceFile): inps.method = 'maxCoherence' else: inps.method = 'random' print('reference point selection method: ' + str(inps.method)) print('-' * 50) return inps
def transect_yx(z, atr, start_yx, end_yx, interpolation='nearest'): """Extract 2D matrix (z) value along the line [x0,y0;x1,y1] Ref link: http://stackoverflow.com/questions/7878398/how-to-e xtract-an-arbitrary-line-of-values-from-a-numpy-array Inputs: z - (np.array) 2D data matrix atr - (dictionary) 2D data matrix attribute dictionary start_yx - (list) y,x coordinate of start point end_yx - (list) y,x coordinate of end point interpolation - sampling/interpolation method, including: 'nearest' - nearest neighbour, by default 'cubic' - cubic interpolation 'bilinear' - bilinear interpolation Output: transect - N*2 matrix containing distance - 1st col - and its corresponding values - 2nd col - along the line, N is the number of points. Example: transect = transect_yx(dem,demRsc,[10,15],[100,115]) """ # Extract the line [y0, x0] = start_yx [y1, x1] = end_yx length = int(np.hypot(x1 - x0, y1 - y0)) x, y = np.linspace(x0, x1, length), np.linspace(y0, y1, length) transect = np.zeros([length, 2]) # Y - Extract the value along the line if interpolation.lower() == 'nearest': zi = z[np.rint(y).astype(np.int), np.rint(x).astype(np.int)] elif interpolation.lower() == 'cubic': zi = scipy.ndimage.map_coordinates(z, np.vstack((y, x))) elif interpolation.lower() == 'bilinear': zi = scipy.ndimage.map_coordinates(z, np.vstack((y, x)), order=2) else: print('Unrecognized interpolation method: ' + interpolation) print('Continue with nearest ...') zi = z[np.rint(y).astype(np.int), np.rint(x).astype(np.int)] # nearest neighbour transect[:, 1] = zi # X - Distance along the line earth_radius = 6371.0e3 # in meter coord = ut.coordinate(atr) try: atr['X_FIRST'] [lat0, lat1] = coord.yx2lalo([y0, y1], coord_type='y') lat_c = (lat0 + lat1) / 2. x_step = float(atr['X_STEP']) * np.pi / 180.0 * earth_radius * np.cos( lat_c * np.pi / 180) y_step = float(atr['Y_STEP']) * np.pi / 180.0 * earth_radius except: x_step = ut.range_ground_resolution(atr) y_step = ut.azimuth_ground_resolution(atr) dis_x = (x - x0) * x_step dis_y = (y - y0) * y_step transect[:, 0] = np.hypot(dis_x, dis_y) return transect
def get_date12_to_drop(inps): """Get date12 list to dropped Return [] if no ifgram to drop, thus KEEP ALL ifgrams; None if nothing to change, exit without doing anything. """ obj = ifgramStack(inps.file) obj.open() date12ListAll = obj.date12List dateList = obj.dateList print('number of interferograms: {}'.format(len(date12ListAll))) # Get date12_to_drop date12_to_drop = [] # reference file if inps.referenceFile: date12_to_keep = ifgramStack(inps.referenceFile).get_date12_list(dropIfgram=True) print('--------------------------------------------------') print('use reference pairs info from file: {}'.format(inps.referenceFile)) print('number of interferograms in reference: {}'.format(len(date12_to_keep))) tempList = sorted(list(set(date12ListAll) - set(date12_to_keep))) date12_to_drop += tempList print('date12 not in reference file: ({})\n{}'.format(len(tempList), tempList)) # coherence file if inps.coherenceBased: print('--------------------------------------------------') print('use coherence-based network modification') coord = ut.coordinate(obj.metadata, lookup_file=inps.lookupFile) if inps.aoi_geo_box and inps.lookupFile: print('input AOI in (lon0, lat1, lon1, lat0): {}'.format(inps.aoi_geo_box)) inps.aoi_pix_box = coord.bbox_geo2radar(inps.aoi_geo_box) if inps.aoi_pix_box: inps.aoi_pix_box = coord.check_box_within_data_coverage(inps.aoi_pix_box) print('input AOI in (x0,y0,x1,y1): {}'.format(inps.aoi_pix_box)) # Calculate spatial average coherence cohList = ut.spatial_average(inps.file, datasetName='coherence', maskFile=inps.maskFile, box=inps.aoi_pix_box, saveList=True)[0] coh_date12_list = list(np.array(date12ListAll)[np.array(cohList) >= inps.minCoherence]) # MST network if inps.keepMinSpanTree: print('Get minimum spanning tree (MST) of interferograms with inverse of coherence.') msg = ('Drop ifgrams with ' '1) average coherence < {} AND ' '2) not in MST network: '.format(inps.minCoherence)) mst_date12_list = pnet.threshold_coherence_based_mst(date12ListAll, cohList) mst_date12_list = ptime.yyyymmdd_date12(mst_date12_list) else: msg = 'Drop ifgrams with average coherence < {}: '.format(inps.minCoherence) mst_date12_list = [] tempList = sorted(list(set(date12ListAll) - set(coh_date12_list + mst_date12_list))) date12_to_drop += tempList msg += '({})'.format(len(tempList)) if len(tempList) <= 200: msg += '\n{}'.format(tempList) print(msg) # temp baseline threshold if inps.tempBaseMax: tempIndex = np.abs(obj.tbaseIfgram) > inps.tempBaseMax tempList = list(np.array(date12ListAll)[tempIndex]) date12_to_drop += tempList print('--------------------------------------------------') print('Drop ifgrams with temporal baseline > {} days: ({})\n{}'.format( inps.tempBaseMax, len(tempList), tempList)) # perp baseline threshold if inps.perpBaseMax: tempIndex = np.abs(obj.pbaseIfgram) > inps.perpBaseMax tempList = list(np.array(date12ListAll)[tempIndex]) date12_to_drop += tempList print('--------------------------------------------------') print('Drop ifgrams with perp baseline > {} meters: ({})\n{}'.format( inps.perpBaseMax, len(tempList), tempList)) # connection number threshold if inps.connNumMax: seq_date12_list = pnet.select_pairs_sequential(dateList, inps.connNumMax) seq_date12_list = ptime.yyyymmdd_date12(seq_date12_list) tempList = [i for i in date12ListAll if i not in seq_date12_list] date12_to_drop += tempList print('--------------------------------------------------') msg = 'Drop ifgrams with temporal baseline beyond {} neighbors: ({})'.format( inps.connNumMax, len(tempList)) if len(tempList) <= 200: msg += '\n{}'.format(tempList) print(msg) # excludeIfgIndex if inps.excludeIfgIndex: tempList = [date12ListAll[i] for i in inps.excludeIfgIndex] date12_to_drop += tempList print('--------------------------------------------------') print('Drop ifgrams with the following index number: {}'.format(len(tempList))) for i in range(len(tempList)): print('{} : {}'.format(i, tempList[i])) #len(tempList), zip(inps.excludeIfgIndex, tempList))) # excludeDate if inps.excludeDate: tempList = [i for i in date12ListAll if any(j in inps.excludeDate for j in i.split('_'))] date12_to_drop += tempList print('-'*50+'\nDrop ifgrams including the following dates: ({})\n{}'.format( len(tempList), inps.excludeDate)) print('-'*30+'\n{}'.format(tempList)) # startDate if inps.startDate: minDate = int(inps.startDate) tempList = [i for i in date12ListAll if any(int(j) < minDate for j in i.split('_'))] date12_to_drop += tempList print('--------------------------------------------------') print('Drop ifgrams with date earlier than: {} ({})\n{}'.format( inps.startDate, len(tempList), tempList)) # endDate if inps.endDate: maxDate = int(inps.endDate) tempList = [i for i in date12ListAll if any(int(j) > maxDate for j in i.split('_'))] date12_to_drop += tempList print('--------------------------------------------------') print('Drop ifgrams with date later than: {} ({})\n{}'.format( inps.endDate, len(tempList), tempList)) # Manually drop pairs if inps.manual: tempList = manual_select_pairs_to_remove(inps.file) if tempList is None: return None tempList = [i for i in tempList if i in date12ListAll] print('date12 selected to remove: ({})\n{}'.format(len(tempList), tempList)) date12_to_drop += tempList # drop duplicate date12 and sort in order date12_to_drop = sorted(list(set(date12_to_drop))) date12_to_keep = sorted(list(set(date12ListAll) - set(date12_to_drop))) print('--------------------------------------------------') print('number of interferograms to remove: {}'.format(len(date12_to_drop))) print('number of interferograms to keep : {}'.format(len(date12_to_keep))) date_to_keep = [d for date12 in date12_to_keep for d in date12.split('_')] date_to_keep = sorted(list(set(date_to_keep))) date_to_drop = sorted(list(set(dateList) - set(date_to_keep))) if len(date_to_drop) > 0: print('number of acquisitions to remove: {}\n{}'.format(len(date_to_drop), date_to_drop)) date12ListKept = obj.get_date12_list(dropIfgram=True) date12ListDropped = sorted(list(set(date12ListAll) - set(date12ListKept))) if date12_to_drop == date12ListDropped: print('Calculated date12 to drop is the same as exsiting marked input file, skip updating file.') date12_to_drop = None elif date12_to_drop == date12ListAll: raise Exception('Zero interferogram left! Please adjust your setting and try again.') return date12_to_drop
def read_insar(self): # 2.1 prepare interpolation coord = ut.coordinate(self.metadata, lookup_file=self.geom_file) lats = [self.ds[k]['lat'] for k in self.ds.keys()] lons = [self.ds[k]['lon'] for k in self.ds.keys()] geo_box = (min(lons), max(lats), max(lons), min(lats)) #(W, N, E, S) pix_box = coord.bbox_geo2radar(geo_box) #(400, 1450, 550, 1600) src_lat = readfile.read(self.geom_file, datasetName='latitude', box=pix_box)[0].reshape(-1, 1) src_lon = readfile.read(self.geom_file, datasetName='longitude', box=pix_box)[0].reshape(-1, 1) src_pts = np.hstack((src_lat, src_lon)) dest_pts = np.zeros((self.num_site, 2)) for i in range(self.num_site): site = self.ds[self.site_names[i]] dest_pts[i, :] = site['lat'], site['lon'] # 2.2 interpolation - displacement / temporal coherence interp_method = 'linear' #nearest, linear, cubic src_value, atr = readfile.read(self.insar_file, box=pix_box) src_value = src_value.reshape(self.num_date, -1) if atr['FILE_TYPE'] == 'giantTimeseries': src_value *= 0.001 insar_dis = np.zeros((self.num_site, self.num_date)) for i in range(self.num_date): insar_dis[:, i] = griddata(src_pts, src_value[i, :], dest_pts, method=interp_method) sys.stdout.write( ('\rreading InSAR acquisition {}/{}' ' with {} interpolation').format(i + 1, self.num_date, interp_method)) sys.stdout.flush() print() print('reading temporal coherence') src_value = readfile.read(self.temp_coh_file, box=pix_box)[0].flatten() temp_coh = griddata(src_pts, src_value, dest_pts, method=interp_method) # 2.3 write interpolation result self.insar_dis_name = 'insar_dis_{}'.format(interp_method) insar_dis_ref = insar_dis[self.site_names.index(self.ref_site), :] for i in range(self.num_site): site = self.ds[self.site_names[i]] site['insar_datetime'] = self.insar_datetime site[self.insar_dis_name] = insar_dis[ i, :] - insar_dis_ref # reference insar to the precise location in space site['temp_coh'] = temp_coh[i] # 2.4 reference insar and gps to a common date print('reference insar and gps to a common date') for i in range(self.num_site): site = self.ds[self.site_names[i]] gps_date = site['gps_datetime'] insar_date = site['insar_datetime'] # find common reference date idx = 5 while idx < self.num_date: if insar_date[idx] not in gps_date: idx += 1 else: break if idx == self.num_date: raise RuntimeError( 'InSAR and GPS do not share ANY date for site: {}'.format( site['name'])) comm_date = insar_date[idx] # reference insar in time site[self.insar_dis_name] -= site[self.insar_dis_name][idx] # reference gps dis/std in time idx_gps = np.where(gps_date == comm_date)[0][0] site['gps_dis'] -= site['gps_dis'][idx_gps] site['gps_std'] = np.sqrt(site['gps_std']**2 + site['gps_std'][idx_gps]**2) site['gps_std_mean'] = np.mean(site['gps_std'])
def subset_file(fname, subset_dict_input, out_file=None): """Subset file with Inputs: fname : str, path/name of file out_file : str, path/name of output file subset_dict : dict, subsut parameter, including the following items: subset_x : list of 2 int, subset in x direction, default=None subset_y : list of 2 int, subset in y direction, default=None subset_lat : list of 2 float, subset in lat direction, default=None subset_lon : list of 2 float, subset in lon direction, default=None fill_value : float, optional. filled value for area outside of data coverage. default=None None/not-existed to subset within data coverage only. tight : bool, tight subset or not, for lookup table file, i.e. geomap*.trans Outputs: out_file : str, path/name of output file; out_file = 'subset_'+fname, if fname is in current directory; out_file = fname, if fname is not in the current directory. """ # Input File Info try: atr = readfile.read_attribute(fname) except: return None width = int(atr['WIDTH']) length = int(atr['LENGTH']) k = atr['FILE_TYPE'] print('subset ' + k + ' file: ' + fname + ' ...') subset_dict = subset_dict_input.copy() # Read Subset Inputs into 4-tuple box in pixel and geo coord pix_box, geo_box = subset_input_dict2box(subset_dict, atr) coord = ut.coordinate(atr) # if fill_value exists and not None, subset data and fill assigned value for area out of its coverage. # otherwise, re-check subset to make sure it's within data coverage and initialize the matrix with np.nan outfill = False if 'fill_value' in subset_dict.keys() and subset_dict['fill_value']: outfill = True else: outfill = False if not outfill: pix_box = coord.check_box_within_data_coverage(pix_box) subset_dict['fill_value'] = np.nan geo_box = coord.box_pixel2geo(pix_box) data_box = (0, 0, width, length) print('data range in y/x: ' + str(data_box)) print('subset range in y/x: ' + str(pix_box)) print('data range in lat/lon: ' + str(coord.box_pixel2geo(data_box))) print('subset range in lat/lon: ' + str(geo_box)) if pix_box == data_box: print('Subset range == data coverage, no need to subset. Skip.') return fname # Calculate Subset/Overlap Index pix_box4data, pix_box4subset = get_box_overlap_index(data_box, pix_box) ########################### Data Read and Write ###################### # Output File Name if not out_file: if os.getcwd() == os.path.dirname(os.path.abspath(fname)): if 'tight' in subset_dict.keys() and subset_dict['tight']: out_file = '{}_tight{}'.format( os.path.splitext(fname)[0], os.path.splitext(fname)[1]) else: out_file = 'subset_' + os.path.basename(fname) else: out_file = os.path.basename(fname) print('writing >>> ' + out_file) # subset datasets one by one dsNames = readfile.get_dataset_list(fname) maxDigit = max([len(i) for i in dsNames]) dsDict = dict() for dsName in dsNames: print('subsetting {d:<{w}} from {f} ...'.format( d=dsName, w=maxDigit, f=os.path.basename(fname))) data = readfile.read(fname, datasetName=dsName, print_msg=False)[0] # subset 2D data if len(data.shape) == 2: data_overlap = data[pix_box4data[1]:pix_box4data[3], pix_box4data[0]:pix_box4data[2]] data = np.ones((pix_box[3] - pix_box[1], pix_box[2] - pix_box[0]), data.dtype) * subset_dict['fill_value'] data[pix_box4subset[1]:pix_box4subset[3], pix_box4subset[0]:pix_box4subset[2]] = data_overlap # subset 3D data elif len(data.shape) == 3: data_overlap = data[:, pix_box4data[1]:pix_box4data[3], pix_box4data[0]:pix_box4data[2]] data = np.ones( (data.shape[0], pix_box[3] - pix_box[1], pix_box[2] - pix_box[0]), data.dtype) * subset_dict['fill_value'] data[:, pix_box4subset[1]:pix_box4subset[3], pix_box4subset[0]:pix_box4subset[2]] = data_overlap dsDict[dsName] = data atr = ut.subset_attribute(atr, pix_box) writefile.write(dsDict, out_file=out_file, metadata=atr, ref_file=fname) return out_file